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.
8 * Set of predefined instruction forms (via procedure calls), providing
9 * a more concise way of specifying opcodes.
12 #ifndef NACL_TRUSTED_BUT_NOT_TCB
13 #error("This file is not meant for use in the TCB")
16 #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_forms.h"
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"
36 /* To turn on debugging of instruction decoding, change value of
41 #include "native_client/src/shared/utils/debugging.h"
43 /* Returns the name for the given enumerated value. */
44 static const char* NaClInstCatName(NaClInstCat cat) {
50 { UnarySet , "UnarySet" },
51 { UnaryUpdate , "UnaryUpdate" },
54 { Binary , "Binary" },
55 { O2Binary , "O2Binary" },
59 { Compare , "Compare"},
60 { Exchange, "Exchange" },
64 { SysCall, "SysCall"},
65 { SysJump, "SysJump"},
75 for (i = 0; i < NACL_ARRAY_SIZE(cat_desc); ++i) {
76 if (cat == cat_desc[i].cat) return cat_desc[i].name;
78 /* Shouldn't be reached!! */
79 NaClFatal("Unrecognized category");
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.
88 static NaClOpFlags NaClGetArg1Flags(NaClInstCat icat, int num_ops) {
89 DEBUG(NaClLog(LOG_INFO, "NaClGetArg1Flags(%s)\n", NaClInstCatName(icat)));
104 return NACL_OPFLAG(OpSet);
112 return NACL_OPFLAG(OpSet) | NACL_OPFLAG(OpUse);
115 return NACL_OPFLAG(OpSet);
117 return NACL_OPFLAG(OpSet) | NACL_OPFLAG(OpUse);
121 return NACL_OPFLAG(OpUse);
123 return NACL_EMPTY_OPFLAGS;
126 NaClFatal("NaClGetArg1Flags: unrecognized category");
128 return NACL_EMPTY_OPFLAGS;
132 /* Returns the OpSet, OpUse, and OpDest operand flags for the source argument(s)
133 * of an instruction, given the category of instruction.
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.
138 * Argument op_index is the actual index of the operand in the
139 * instruction being modeled.
141 static NaClOpFlags NaClGetArg2PlusFlags(NaClInstCat icat,
144 DEBUG(NaClLog(LOG_INFO, "NaClGetArgsPlusFlags(%s, %d)\n",
145 NaClInstCatName(icat), visible_index));
149 NaClLog(LOG_INFO, "icat = %s\n", NaClInstCatName(icat));
150 NaClFatal("Illegal to use unary categorization for binary operation");
152 return NACL_EMPTY_OPFLAGS;
157 return NACL_OPFLAG(OpSet) | NACL_OPFLAG(OpUse);
159 return NACL_OPFLAG(OpUse);
163 return NACL_OPFLAG(OpSet);
165 return NACL_OPFLAG(OpUse);
176 return NACL_OPFLAG(OpUse);
178 if ((2 == op_index)) {
179 return NACL_OPFLAG(OpSet);
181 return NACL_OPFLAG(OpUse);
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);
189 return NACL_OPFLAG(OpSet) | NACL_OPFLAG(OpUse);
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);
196 return NACL_OPFLAG(OpSet) | NACL_OPFLAG(OpUse);
199 return NACL_OPFLAG(OpUse);
204 return NACL_OPFLAG(OpSet);
207 return NACL_OPFLAG(OpSet);
209 return NACL_OPFLAG(OpUse);
213 return NACL_EMPTY_OPFLAGS;
216 return NACL_OPFLAG(OpSet);
218 return NACL_OPFLAG(OpSet) | NACL_OPFLAG(OpUse);
221 NaClFatal("NaClGetArg2PlusFlags: unrecognized category");
223 return NACL_EMPTY_OPFLAGS;
227 /* Returns the OpSet and OpUse operand flags for the operand
228 * with the given operand_index (1-based) argument for the instruction,
230 * Argument icat is the instruction category of the instruction being
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.
236 * Argument op_index is the actual index of the operand in the
237 * instruction being modeled.
239 * Argument num_ops is the number of operands the instruction has (base 1).
241 static NaClOpFlags NaClGetIcatFlags(NaClInstCat icat,
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);
251 flags = NaClGetArg2PlusFlags(icat, visible_count, operand_index);
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"));
269 /* Adds OpSet/OpUse flags to operands to the current instruction,
270 * based on the given instruction categorization.
272 static void NaClSetInstCat(NaClInstCat icat) {
273 int operand_index = 0; /* note: this is one-based. */
274 int visible_count = 0;
277 NaClModeledInst* inst = NaClGetDefInst();
278 num_ops = inst->num_operands;
279 for (i = 0; i < num_ops; ++i) {
280 Bool is_visible = FALSE;
282 if (NACL_EMPTY_OPFLAGS ==
283 (inst->operands[i].flags & NACL_OPFLAG(OpImplicit))) {
287 NaClAddOpFlags(i, NaClGetIcatFlags(
288 icat, operand_index, (is_visible ? visible_count : 0), num_ops));
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.
293 if ((Binary == icat) && (3 == num_ops)) {
294 NaClRemoveOpFlags(0, NACL_OPFLAG(OpUse));
296 NaClAddMiscellaneousFlags();
299 /* Returns true if opcode sequence value is a SL (slash)
302 static Bool IsSLValue(int16_t val) {
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);
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.
317 * prefix_count - Variable to update on number of matched prefix
319 * inst - The instruction we are matching the opcode sequence against.
320 * name_and_opcode_seq - The opcode sequence descriptor we are trying
323 static Bool NaClNameOpcodeSeqMatchesPrefixByte(
325 NaClModeledInst* inst,
326 const NaClNameOpcodeSeq* name_and_opcode_seq,
329 switch (inst->prefix) {
345 if (prefix == name_and_opcode_seq[index].opcode_seq[0]) {
353 Bool NaClInInstructionSet(const NaClMnemonic* names,
355 const NaClNameOpcodeSeq* name_and_opcode_seq,
356 size_t name_and_opcode_seq_size) {
358 NaClModeledInst* inst = NaClGetDefInst();
360 /* First handle cases where all instances of an instruction
361 * mnemonic is in the set.
363 for (i = 0; i < names_size; ++i) {
364 if (inst->name == names[i]) {
369 /* How handle cases where only a specific opcode sequence of
370 * an instruction mnemonic applies.
372 for (i = 0; i < name_and_opcode_seq_size; ++i) {
373 if (inst->name == name_and_opcode_seq[i].name) {
375 int prefix_count = 0;
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]) {
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.
400 if (inst->flags & NACL_IFLAG(OpcodeInModRm)) {
401 return matched_slash;
403 /* At end of descriptor, matched! */
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;
424 /* If reached, couldn't match, so not in instruction set. */
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));
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
438 NaClDefOp(C_Operand, NACL_EMPTY_OPFLAGS);
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
446 NaClDefOp(D_Operand, NACL_EMPTY_OPFLAGS);
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.
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);
461 NaClDefOp(E_Operand, NACL_EMPTY_OPFLAGS);
462 NaClAddIFlags(NACL_IFLAG(OperandSize_b));
466 static void NaClOperandForm_Ed(void) {
467 NaClDefOp(Ev_Operand, NACL_EMPTY_OPFLAGS);
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.
474 NaClDefOp(E_Operand, NACL_EMPTY_OPFLAGS);
475 NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(OperandSize_o) |
476 NACL_IFLAG(SizeIgnoresData16));
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.
484 NaClDefOp(E_Operand, NACL_EMPTY_OPFLAGS);
485 NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(SizeIgnoresData16));
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.
493 NaClDefOp(E_Operand, NACL_EMPTY_OPFLAGS);
494 NaClAddIFlags(NACL_IFLAG(OperandSize_o) | NACL_IFLAG(SizeIgnoresData16));
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));
503 static void NaClOperandForm_Ew(void) {
504 NaClDefOp(Ew_Operand, NACL_EMPTY_OPFLAGS);
507 static void NaClOperandForm_Fvw(void) {
508 NaClDefOp(RegRFLAGS, NACL_EMPTY_OPFLAGS);
509 NaClAddIFlags(NACL_IFLAG(OperandSize_w));
512 static void NaClOperandForm_Fvd(void) {
513 NaClDefOp(RegRFLAGS, NACL_EMPTY_OPFLAGS);
514 NaClAddIFlags(NACL_IFLAG(OperandSize_v));
517 static void NaClOperandForm_Fvq(void) {
518 NaClDefOp(RegRFLAGS, NACL_EMPTY_OPFLAGS);
519 NaClAddIFlags(NACL_IFLAG(OperandSize_o));
522 static void NaClOperandForm_Gb(void) {
523 NaClDefOp(G_Operand, NACL_EMPTY_OPFLAGS);
524 NaClAddIFlags(NACL_IFLAG(OperandSize_b));
527 static void NaClOperandForm_Gd(void) {
528 NaClDefOp(Gv_Operand, NACL_EMPTY_OPFLAGS);
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.
535 NaClDefOp(G_Operand, NACL_EMPTY_OPFLAGS);
536 NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(OperandSize_o) |
537 NACL_IFLAG(SizeIgnoresData16));
540 static void NaClOperandForm_Gq(void) {
541 NaClDefOp(Go_Operand, NACL_EMPTY_OPFLAGS);
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));
550 static void NaClOperandForm_Gw(void) {
551 NaClDefOp(Gw_Operand, NACL_EMPTY_OPFLAGS);
554 static void NaClOperandForm_Ib(void) {
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.
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));
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));
573 NaClAddIFlags(NACL_IFLAG(OpcodeHasImmed_b));
577 static void NaClOperandForm_I2b(void) {
578 NaClDefOp(I2_Operand, NACL_EMPTY_OPFLAGS);
579 NaClAddIFlags(NACL_IFLAG(OpcodeHasImmed2_b));
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));
588 static void NaClOperandForm_Iw(void) {
589 NaClDefOp(I_Operand, NACL_EMPTY_OPFLAGS);
590 NaClAddIFlags(NACL_IFLAG(OpcodeHasImmed_w));
593 static void NaClOperandForm_Iz(void) {
594 NaClDefOp(I_Operand, NACL_EMPTY_OPFLAGS);
595 NaClAddIFlags(NACL_IFLAG(OpcodeHasImmed_z));
598 static void NaClOperandForm_Jb(void) {
600 NACL_OPFLAG(OperandRelative) | NACL_OPFLAG(OperandNear));
601 NaClAddIFlags(NACL_IFLAG(OpcodeHasImmed) | NACL_IFLAG(OperandSize_b));
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.
608 static void DefOperandJzBaseUseImmedV(Bool use_immed_v) {
610 NACL_OPFLAG(OperandRelative) | NACL_OPFLAG(OperandNear));
612 NaClAddIFlags(NACL_IFLAG(OpcodeHasImmed_v));
614 NaClAddIFlags(NACL_IFLAG(OpcodeHasImmed_z));
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").
627 DefOperandJzBaseUseImmedV(X86_64 == NACL_FLAGS_run_mode);
630 static void NaClOperandForm_Jz(void) {
632 NaClAddIFlags(NACL_IFLAG(OperandSize_w) | NACL_IFLAG(OperandSize_v) |
633 NACL_IFLAG(OperandSize_o));
636 static void NaClOperandForm_Jzd(void) {
637 DefOperandJzBaseUseImmedV(TRUE);
638 NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(OperandSize_o));
641 static void NaClOperandForm_Jzw(void) {
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").
649 if (X86_64 == NACL_FLAGS_run_mode) {
650 NaClAddIFlags(NACL_IFLAG(NaClIllegal));
654 static void NaClOperandForm_M(void) {
655 NaClDefOp(M_Operand, NACL_EMPTY_OPFLAGS);
656 NaClAddIFlags(NACL_IFLAG(OpcodeAllowsData16));
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));
665 static void NaClOperandForm_Mb(void) {
666 NaClDefOp(Mb_Operand, NACL_EMPTY_OPFLAGS);
669 static void NaClOperandForm_Md(void) {
670 NaClDefOp(Mv_Operand, NACL_EMPTY_OPFLAGS);
673 static void NaClOperandForm_Mdq(void) {
674 NaClDefOp(Mdq_Operand, NACL_EMPTY_OPFLAGS);
677 static void NaClOperandForm_Mf(void) {
678 NaClDefOp(M_Operand, NACL_EMPTY_OPFLAGS);
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.
685 NaClDefOp(M_Operand, NACL_EMPTY_OPFLAGS);
686 NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(OperandSize_o) |
687 NACL_IFLAG(SizeIgnoresData16));
690 static void NaClOperandForm_Mp(void) {
691 /* TODO(karl) fix measurement size. */
692 NaClDefOp(M_Operand, NACL_OPFLAG(OperandFar));
695 static void NaClOperandForm_Ms(void) {
696 /* TODO(karl): fix size of data accessed in memory. */
697 NaClDefOp(M_Operand, NACL_EMPTY_OPFLAGS);
700 static void NaClOperandForm_Mq(void) {
701 NaClDefOp(Mo_Operand, NACL_EMPTY_OPFLAGS);
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));
710 static void NaClOperandForm_Mw(void) {
711 NaClDefOp(Mw_Operand, NACL_EMPTY_OPFLAGS);
714 static void NaClOperandForm_MwSlRv(void) {
715 /* TODO(karl) Verify that Mw/Rv as same as Ev? */
716 NaClOperandForm_Ev();
719 static void NaClOperandForm_Ob(void) {
720 NaClDefOp(O_Operand, NACL_EMPTY_OPFLAGS);
721 NaClAddIFlags(NACL_IFLAG(OperandSize_b) | NACL_IFLAG(OpcodeHasImmed_Addr));
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));
731 static void NaClOperandForm_One(void) {
732 NaClDefOp(Const_1, NACL_EMPTY_OPFLAGS);
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.
739 NaClDefOp(Mmx_G_Operand, NACL_EMPTY_OPFLAGS);
740 NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(OperandSize_o) |
741 NACL_IFLAG(SizeIgnoresData16));
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.
749 NaClDefOp(Mmx_G_Operand, NACL_EMPTY_OPFLAGS);
750 NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(SizeIgnoresData16));
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.
758 NaClDefOp(Mmx_G_Operand, NACL_EMPTY_OPFLAGS);
759 NaClAddIFlags(NACL_IFLAG(OperandSize_o) | NACL_IFLAG(SizeIgnoresData16));
762 static void NaClOperandForm_Pq(void) {
763 /* TODO(karl) Add q size restriction. */
764 NaClDefOp(Mmx_G_Operand, NACL_EMPTY_OPFLAGS);
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.
771 NaClDefOp(Mmx_N_Operand, NACL_EMPTY_OPFLAGS);
774 static void NaClOperandForm_Qd(void) {
775 /* TODO(karl) add d size restriction. */
776 NaClDefOp(Mmx_E_Operand, NACL_EMPTY_OPFLAGS);
779 static void NaClOperandForm_Qq(void) {
780 /* TODO(karl) add q size restriction. */
781 NaClDefOp(Mmx_E_Operand, NACL_EMPTY_OPFLAGS);
784 static void NaClOperandForm_Rd(void) {
785 NaClDefOp(Ev_Operand, NACL_EMPTY_OPFLAGS);
786 NaClAddIFlags(NACL_IFLAG(ModRmModIs0x3));
789 static void NaClOperandForm_Rq(void) {
790 NaClDefOp(Eo_Operand, NACL_EMPTY_OPFLAGS);
791 NaClAddIFlags(NACL_IFLAG(ModRmModIs0x3));
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.
798 NaClDefOp(Ev_Operand, NACL_EMPTY_OPFLAGS);
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.
805 NaClDefOp(Ev_Operand, NACL_EMPTY_OPFLAGS);
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
813 if (X86_32 == NACL_FLAGS_run_mode) {
814 NaClOperandForm_Rd();
816 NaClOperandForm_Rq();
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.
824 NaClOperandForm_EdSlq();
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.
831 NaClOperandForm_EdSlq();
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));
840 static void NaClOperandForm_rAXva(void) {
841 NaClDefOp(RegREAXa, NACL_EMPTY_OPFLAGS);
844 static void NaClOperandForm_rAXvd(void) {
845 NaClDefOp(RegEAX, NACL_EMPTY_OPFLAGS);
846 NaClAddIFlags(NACL_IFLAG(OperandSize_v));
849 static void NaClOperandForm_rAXvq(void) {
850 NaClDefOp(RegRAX, NACL_EMPTY_OPFLAGS);
851 NaClAddIFlags(NACL_IFLAG(OperandSize_o));
854 static void NaClOperandForm_rAXvw(void) {
855 NaClDefOp(RegAX, NACL_EMPTY_OPFLAGS);
856 NaClAddIFlags(NACL_IFLAG(OperandSize_w));
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));
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));
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));
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));
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));
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));
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));
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.
907 static void NaClOperandForm_r8b(void) {
908 NaClDefOp(G_OpcodeBase, NACL_EMPTY_OPFLAGS);
909 NaClAddIFlags(NACL_IFLAG(OperandSize_b));
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.
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));
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.
929 static void NaClOperandForm_r8vd(void) {
930 NaClDefOp(G_OpcodeBase, NACL_EMPTY_OPFLAGS);
931 NaClAddIFlags(NACL_IFLAG(OperandSize_v));
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.
940 static void NaClOperandForm_r8vq(void) {
941 NaClDefOp(G_OpcodeBase, NACL_EMPTY_OPFLAGS);
942 NaClAddIFlags(NACL_IFLAG(OperandSize_o));
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));
951 static void NaClOperandForm_Sw(void) {
952 NaClDefOp(S_Operand, NACL_EMPTY_OPFLAGS);
953 NaClAddIFlags(NACL_IFLAG(ModRmRegSOperand));
956 static void NaClOperandForm_Udq(void) {
957 NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
960 static void NaClOperandForm_UdqMd(void) {
961 /* TODO: how to define size, based on register (Udq) or
964 NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
967 static void NaClOperandForm_UdqMq(void) {
968 /* TODO: how to define size, based on register (Udq) or
971 NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
974 static void NaClOperandForm_UdqMw(void) {
975 /* TODO: how to define size, based on register (Udq) or
978 NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
981 static void NaClOperandForm_Vdq(void) {
982 /* TODO(karl) Add dq size restriction. */
983 NaClDefOp(Xmm_G_Operand, NACL_EMPTY_OPFLAGS);
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.
990 NaClDefOp(Xmm_G_Operand, NACL_EMPTY_OPFLAGS);
991 NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(OperandSize_o) |
992 NACL_IFLAG(SizeIgnoresData16));
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.
1000 NaClDefOp(Xmm_G_Operand, NACL_EMPTY_OPFLAGS);
1001 NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(SizeIgnoresData16));
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.
1009 NaClDefOp(Xmm_G_Operand, NACL_EMPTY_OPFLAGS);
1010 NaClAddIFlags(NACL_IFLAG(OperandSize_o) | NACL_IFLAG(SizeIgnoresData16));
1013 static void NaClOperandForm_Vpd(void) {
1014 NaClDefOp(Xmm_G_Operand, NACL_EMPTY_OPFLAGS);
1017 static void NaClOperandForm_Vps(void) {
1018 NaClDefOp(Xmm_G_Operand, NACL_EMPTY_OPFLAGS);
1021 static void NaClOperandForm_Vq(void) {
1022 NaClDefOp(Xmm_Go_Operand, NACL_EMPTY_OPFLAGS);
1025 static void NaClOperandForm_Vsd(void) {
1026 NaClDefOp(Xmm_G_Operand, NACL_EMPTY_OPFLAGS);
1029 static void NaClOperandForm_Vss(void) {
1030 NaClDefOp(Xmm_G_Operand, NACL_EMPTY_OPFLAGS);
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.
1037 NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
1038 NaClAddIFlags(NACL_IFLAG(ModRmModIs0x3));
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.
1045 NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
1046 NaClAddIFlags(NACL_IFLAG(ModRmModIs0x3));
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.
1053 NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
1054 NaClAddIFlags(NACL_IFLAG(ModRmModIs0x3));
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.
1061 NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
1062 NaClAddIFlags(NACL_IFLAG(ModRmModIs0x3));
1065 static void NaClOperandForm_Wdq(void) {
1066 /* TODO(karl) Add dq size restriction. */
1067 NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
1070 static void NaClOperandForm_Wpd(void) {
1071 NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
1074 static void NaClOperandForm_Wps(void) {
1075 NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
1078 static void NaClOperandForm_Wq(void) {
1079 /* TODO(karl) Add q size restriction. */
1080 NaClDefOp(Xmm_Eo_Operand, NACL_EMPTY_OPFLAGS);
1083 static void NaClOperandForm_Wsd(void) {
1084 NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
1087 static void NaClOperandForm_Wss(void) {
1088 NaClDefOp(Xmm_E_Operand, NACL_EMPTY_OPFLAGS);
1091 static void NaClOperandForm_Xb(void) {
1092 NaClDefOp(RegDS_ESI, NACL_EMPTY_OPFLAGS);
1093 NaClAddIFlags(NACL_IFLAG(OperandSize_b));
1096 static void NaClOperandForm_Xvw(void) {
1097 NaClDefOp(RegDS_ESI, NACL_EMPTY_OPFLAGS);
1098 NaClAddIFlags(NACL_IFLAG(OperandSize_w));
1101 static void NaClOperandForm_Xvd(void) {
1102 NaClDefOp(RegDS_ESI, NACL_EMPTY_OPFLAGS);
1103 NaClAddIFlags(NACL_IFLAG(OperandSize_v));
1106 static void NaClOperandForm_Xvq(void) {
1107 NaClDefOp(RegDS_ESI, NACL_EMPTY_OPFLAGS);
1108 NaClAddIFlags(NACL_IFLAG(OperandSize_o));
1111 static void NaClOperandForm_Xzd(void) {
1112 NaClDefOp(RegDS_ESI, NACL_EMPTY_OPFLAGS);
1113 NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(OperandSize_o));
1116 static void NaClOperandForm_Xzw(void) {
1117 NaClDefOp(RegDS_ESI, NACL_EMPTY_OPFLAGS);
1118 NaClAddIFlags(NACL_IFLAG(OperandSize_w));
1121 static void NaClOperandForm_Yb(void) {
1122 NaClDefOp(RegES_EDI, NACL_EMPTY_OPFLAGS);
1123 NaClAddIFlags(NACL_IFLAG(OperandSize_b));
1126 static void NaClOperandForm_Yvd(void) {
1127 NaClDefOp(RegES_EDI, NACL_EMPTY_OPFLAGS);
1128 NaClAddIFlags(NACL_IFLAG(OperandSize_v));
1131 static void NaClOperandForm_Yvq(void) {
1132 NaClDefOp(RegES_EDI, NACL_EMPTY_OPFLAGS);
1133 NaClAddIFlags(NACL_IFLAG(OperandSize_o));
1136 static void NaClOperandForm_Yvw(void) {
1137 NaClDefOp(RegES_EDI, NACL_EMPTY_OPFLAGS);
1138 NaClAddIFlags(NACL_IFLAG(OperandSize_w));
1141 static void NaClOperandForm_Yzw(void) {
1142 NaClDefOp(RegES_EDI, NACL_EMPTY_OPFLAGS);
1143 NaClAddIFlags(NACL_IFLAG(OperandSize_w));
1146 static void NaClOperandForm_Yzd(void) {
1147 NaClDefOp(RegES_EDI, NACL_EMPTY_OPFLAGS);
1148 NaClAddIFlags(NACL_IFLAG(OperandSize_v) | NACL_IFLAG(OperandSize_o));
1151 static void NaClOperandForm_Zvd(void) {
1152 NaClDefOp(RegDS_EDI, NACL_EMPTY_OPFLAGS);
1153 NaClAddIFlags(NACL_IFLAG(OperandSize_v));
1156 /**************************************************************************
1157 * The following code is code that takes a opcode description string, and *
1158 * generates the corresponding instruction *
1160 * TODO(karl) Remove macro implementations once we have moved to this new *
1162 *************************************************************************/
1164 /* Define the (maximum) size that working buffers, for the translation code. */
1167 /* Define the maximum number of operands that can appear in an opcode
1168 * description string.
1170 #define MAX_OPERANDS 10
1172 #define MAX_DEFOPS 1000
1174 #define BUF_SIZE 1024
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.
1180 #define MAX_ST_SUBSTITUTIONS 100
1182 /* The current opcode string description being translated. Mainly used
1183 * to generate useful error messages.
1185 static char* kCachedDesc = "???";
1187 /* The set of possible characters that can follow a symbol when doing
1188 * symbol substitution.
1190 static const char* kSymbolTerminators = " :+/{},@";
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);
1197 /* Generates a fatal error message for the cached opcode description string. */
1198 static void NaClDefFatal(const char* message) {
1199 NaClDefDescFatal(kCachedDesc, message);
1202 /* replace all occurrences of "@NAME" with the corresponding
1203 * value in the given symbol table.
1205 * NOTE: only MAX_ST_SUBSTITUTIONS are allowed, to make sure
1206 * that we don't infinite loop.
1208 static void NaClStExpand(char* desc, struct NaClSymbolTable* st) {
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, '@')) {
1216 size_t name_len = 0;
1218 const char *ch_ptr = marker+1;
1219 while (*ch_ptr && (NULL == strchr(kSymbolTerminators, *ch_ptr))) {
1220 name[name_len++] = *(ch_ptr++);
1222 name[name_len] = '\0';
1224 /* Get corresponding symbol table value. */
1225 NaClStValue* val = NaClSymbolTableGet(name, st);
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++);
1237 /* Do substitution of symbol value. */
1238 switch (val->kind) {
1240 SNPRINTF(v_buffer, BUFSIZE, "%02"NACL_PRIx8, val->value.byte_value);
1243 v_buffer_ptr = val->value.text_value;
1246 SNPRINTF(v_buffer, BUFSIZE, "%d", val->value.int_value);
1249 NaClDefDescFatal(desc, "Unable to expand @ variable");
1252 while (*v_buffer_ptr) {
1253 *(buffer_ptr++) = *(v_buffer_ptr++);
1255 /* copy text after @name. */
1258 *(buffer_ptr++) = *(desc_ptr++);
1261 strcpy(desc, buffer);
1266 /* If reached, unable to do substitution, stop. */
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.
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");
1280 if (len != strspn(byte, "0123456789aAbBcCdDeEfF")) {
1281 NaClDefFatal("opcode base not hex value");
1285 /* Given a pointer to a string describing a byte using hexidecimal values,
1286 * extract the corresponding byte value.
1288 * Note: Assumes that the length of base is 2.
1290 static uint8_t NaClExtractByte(const char* base) {
1291 return (uint8_t) STRTOULL(base + strlen(base) - 2, NULL, 16);
1294 /* Given a string of bytes describing a prefix, return the
1295 * corresponding enumerated prefix value.
1297 static NaClInstPrefix NaClExtractPrefixValue(const char* prefix_name,
1298 size_t prefix_size) {
1299 if (prefix_size == 0) {
1303 NaClInstPrefix prefix;
1304 char prefix_text[BUFSIZE];
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]);
1311 text_ptr[prefix_size] = '\0';
1312 for (prefix = 0; prefix < NaClInstPrefixEnumSize; ++prefix) {
1313 if (0 == strcmp(NaClInstPrefixName(prefix), prefix_text)) {
1318 NaClDefFatal("Opcode prefix not understood");
1320 return NaClInstPrefixEnumSize;
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
1328 * Note: Assumes that NaClVerifyByteBaseAssumptions was called
1329 * on the given parameter.
1331 static NaClInstPrefix NaClExtractPrefix(const char* base) {
1332 size_t len = strlen(base);
1334 return NaClExtractPrefixValue(base, len - 2);
1336 NaClDefFatal("Opcode prefix not understood");
1338 return NaClInstPrefixEnumSize;
1341 static void NaClVerifyOctalDigit(const char* str, const char* message) {
1342 if ((1 != strlen(str)) || (1 != strspn(str, "01234567"))) {
1343 NaClDefFatal(message);
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.
1352 * Note: See ??? for descriptions of legal opcode strings.
1354 static void NaClParseOpcode(const char* opcode,
1355 NaClInstType insttype,
1357 struct NaClSymbolTable* st) {
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);
1371 /* Remove leading whitespace. */
1372 while(' ' == *buffer) ++buffer;
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(/).
1378 /* Try to recognize an opcode extension. */
1379 marker = strchr(buffer, '/');
1380 if (NULL != marker) {
1382 opcode_ext = buffer + strlen(base) + 1;
1383 marker = strchr(opcode_ext, '/');
1384 if (NULL != marker) {
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 "
1392 if (strlen(opcode_ext) != 1) {
1393 NaClDefFatal("modrm opcode extension can only be a single digit");
1396 /* Try to recognize a 3dnow extension. */
1397 marker = strchr(buffer, '.');
1398 if ((NULL != marker) && (0 == strncmp(marker, "..", 2))) {
1400 opcode_3d_ext = marker + 2;
1404 marker = strchr(buffer, '+');
1405 if (NULL != marker) {
1407 reg_offset = buffer + strlen(base) + 1;
1410 /* Now verify the opcode string, less the suffix, is valid. If so,
1411 * Pull out the instruction prefix and opcode byte.
1413 NaClVerifyByteBaseAssumptions(base);
1414 if (NULL == opcode_3d_ext) {
1415 prefix = NaClExtractPrefix(base);
1417 prefix = NaClExtractPrefixValue(base, strlen(base));
1419 NaClDefInstPrefix(prefix);
1420 opcode_value = NaClExtractByte(base + strlen(base) - 2);
1422 if (reg_offset != NULL) {
1423 int reg = (int) STRTOULL(reg_offset, NULL, 10);
1425 NaClDefFatal("can't add negative values to opcode");
1426 } else if ((reg + opcode_value) >= NCDTABLESIZE) {
1427 NaClDefFatal("opcode addition too large");
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);
1435 NaClDefInst(opcode_value + reg, insttype, NACL_EMPTY_IFLAGS, name);
1437 is_inst_defined = TRUE;
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);
1444 NaClAddIFlags(NACL_IFLAG(OpcodeUsesModRm));
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);
1452 NaClAddIFlags(NACL_IFLAG(OpcodeInModRm));
1453 NaClDefOpcodeExtension(ext);
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));
1461 if (!is_inst_defined) {
1462 NaClIFlags flags = NACL_EMPTY_IFLAGS;
1463 if (opcode_3d_ext != NULL) {
1464 opcode_value = NaClExtractByte(opcode_3d_ext);
1466 NaClDefInst(opcode_value, insttype, flags, name);
1470 /* Given the text of a mnemonic, return the corresponding mnemonic. */
1471 static NaClMnemonic NaClAssemName(const char* name) {
1473 for (i = (NaClMnemonic) 0; i < NaClMnemonicEnumSize; ++i) {
1474 if (0 == strcmp(NaClMnemonicName(i), name)) {
1478 NaClDefFatal("Can't find name for mnemonic");
1480 return NaClMnemonicEnumSize;
1483 /* Given the name of a register, define the corresponding operand on
1484 * the instruction being defined.
1486 static void NaClExtractRegister(const char* reg_name) {
1487 char buffer[BUFSIZE];
1488 char* buf_ptr = buffer;
1489 char* reg_ptr = (char*) reg_name;
1491 strcpy(buf_ptr, "Reg");
1492 buf_ptr += strlen("Reg");
1494 char ch = *(reg_ptr++);
1495 *(buf_ptr++) = toupper(ch);
1498 for (kind = 0; kind < NaClOpKindEnumSize; ++kind) {
1499 if (0 == strcmp(NaClOpKindName(kind), buffer)) {
1500 NaClDefOp(kind, NACL_EMPTY_OPFLAGS);
1504 NaClDefFatal("Unable to find register");
1507 /* Helper function to add a define operand function into
1510 static void NaClSymbolTablePutDefOp(const char* name,
1511 NaClDefOperand defop,
1512 struct NaClSymbolTable* st) {
1514 value.kind = nacl_defop;
1515 value.value.defop_value = defop;
1516 NaClSymbolTablePut(name, &value, st);
1519 /* Given the name describing legal values for an operand,
1520 * call the corresponding function to define the corresponding
1523 static void NaClExtractOperandForm(const char* form) {
1524 static struct NaClSymbolTable* defop_st = NULL;
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);
1639 value = NaClSymbolTableGet(form, defop_st);
1640 if (NULL == value || (value->kind != nacl_defop)) {
1641 NaClDefFatal("Malformed $defop form");
1643 value->value.defop_value();
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.
1650 * Note: See ??? for descriptions of legal operand strings.
1652 static NaClOpFlags NaClExtractOperand(const char* operand) {
1653 NaClOpFlags op_flags = NACL_EMPTY_OPFLAGS;
1656 if ('}' == operand[strlen(operand) - 1]) {
1657 char buffer[BUFSIZE];
1658 strcpy(buffer, operand+1);
1659 buffer[strlen(buffer)-1] = '\0';
1661 NaClExtractOperand(buffer) |
1662 NACL_OPFLAG(OpImplicit);
1664 NaClDefFatal("Malformed implicit braces");
1668 if (1 == strlen(operand)) {
1669 NaClOperandForm_One();
1671 NaClDefFatal("Malformed operand argument");
1675 NaClExtractRegister(operand+1);
1678 NaClExtractOperandForm(operand+1);
1681 NaClDefFatal("Malformed operand argument");
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.
1690 static void NaClParseOperand(const char* operand, int arg_index) {
1691 NaClAddOpFlags(arg_index, NaClExtractOperand(operand));
1692 NaClAddOpFormat(arg_index, operand);
1695 void NaClBegDef(const char* desc, NaClInstType insttype,
1696 struct NaClSymbolTable* st) {
1700 char buffer[BUFSIZE];
1701 char expanded_desc[BUFSIZE];
1704 NaClMnemonic mnemonic;
1705 char* old_kdesc = kCachedDesc;
1706 kCachedDesc = (char*) desc;
1708 /* Do symbol table substitutions. */
1709 strcpy(buffer, desc);
1710 NaClStExpand(buffer, st);
1711 strcpy(expanded_desc, buffer);
1712 kCachedDesc = expanded_desc;
1714 /* Separate the description into opcode sequence and
1715 * assembly description.
1717 opcode = strtok(buffer, ":");
1718 if (NULL == opcode) {
1719 NaClDefFatal("opcode not separated from assembly description using ':'");
1721 assem_desc = strtok(NULL, ":");
1722 if (NULL == assem_desc) {
1723 NaClDefFatal("Can't find assembly description");
1725 if (NULL != strtok(NULL, ":")) {
1726 NaClDefFatal("Malformed assembly description");
1729 /* extract nmemonic name of instruction. */
1730 name = strtok(assem_desc, " ");
1732 NaClDefFatal("Can't find mnemonic name");
1734 mnemonic = NaClAssemName(name);
1735 NaClDelaySanityChecks();
1736 NaClParseOpcode(opcode, insttype, mnemonic, st);
1738 /* Now extract operands. */
1739 while ((arg = strtok(NULL, ", "))) {
1740 NaClParseOperand(arg, num_args);
1742 if (num_args == MAX_OPERANDS) {
1743 NaClDefFatal("Too many operands");
1746 kCachedDesc = old_kdesc;
1749 void NaClBegD32(const char* desc, NaClInstType insttype,
1750 struct NaClSymbolTable* st) {
1751 NaClBegDef(desc, insttype, st);
1752 NaClAddIFlags(NACL_IFLAG(Opcode32Only));
1755 void NaClBegD64(const char* desc, NaClInstType insttype,
1756 struct NaClSymbolTable* st) {
1757 NaClBegDef(desc, insttype, st);
1758 NaClAddIFlags(NACL_IFLAG(Opcode64Only));
1761 void NaClBegDefPlatform(NaClTargetPlatform platform,
1762 const char* desc, NaClInstType insttype,
1763 struct NaClSymbolTable* st) {
1766 NaClBegD32(desc, insttype, st);
1769 NaClBegD64(desc, insttype, st);
1772 NaClBegDef(desc, insttype, st);
1775 /* This shouldn't happen. */
1776 NaClDefFatal("Don't understand platform");
1780 void NaClEndDef(NaClInstCat icat) {
1781 NaClSetInstCat(icat);
1782 NaClApplySanityChecks();
1783 NaClResetToDefaultInstPrefix();
1786 void NaClDefine(const char* desc, NaClInstType insttype,
1787 struct NaClSymbolTable* st, NaClInstCat cat) {
1788 NaClBegDef(desc, insttype, st);
1792 void NaClDef_32(const char* desc, NaClInstType insttype,
1793 struct NaClSymbolTable* st, NaClInstCat cat) {
1794 NaClBegD32(desc, insttype, st);
1798 void NaClDef_64(const char* desc, NaClInstType insttype,
1799 struct NaClSymbolTable* st, NaClInstCat cat) {
1800 NaClBegD64(desc, insttype, st);
1804 void NaClDefinePlatform(NaClTargetPlatform platform,
1805 const char* desc, NaClInstType insttype,
1806 struct NaClSymbolTable* st, NaClInstCat cat) {
1809 NaClDef_32(desc, insttype, st, cat);
1812 NaClDef_64(desc, insttype, st, cat);
1815 NaClDefine(desc, insttype, st, cat);
1818 /* This shouldn't happen. */
1819 NaClDefFatal("Don't understand platform");
1823 /* Generate an error message for the given instruction description,
1824 * if min <0 or max > 7.
1826 static void NaClDefCheckRange(const char* desc, int min, int max, int cutoff) {
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);
1836 /* Define a symbol table size that can hold a small number of
1837 * symbols (i.e. limit to at most 5 definitions).
1839 #define NACL_SMALL_ST (5)
1841 void NaClDefReg(const char* desc, int min, int max,
1842 NaClInstType insttype, struct NaClSymbolTable* context_st,
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);
1851 NaClSymbolTableDestroy(st);
1854 void NaClDefIter(const char* desc, int min, int max,
1855 NaClInstType insttype, struct NaClSymbolTable* context_st,
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);
1865 NaClSymbolTableDestroy(st);