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

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

Issue 7980021: Speed up x86-64 validator by inlining heavily called routines. Speeds up (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client/
Patch Set: '' Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 /* 7 /*
8 * Translates the recognized opcode (instruction) in the instruction state 8 * Translates the recognized opcode (instruction) in the instruction state
9 * into an opcode expression. 9 * into an opcode expression.
10 */ 10 */
11 11
12 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_trans.h" 12 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_trans.h"
13 13
14 #include <stdio.h> 14 #include <stdio.h>
15 #include <assert.h> 15 #include <assert.h>
16 16
17 #include "native_client/src/shared/platform/nacl_log.h" 17 #include "native_client/src/shared/platform/nacl_log.h"
18 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state.h" 18 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state.h"
19 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal .h" 19 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal .h"
20 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h" 20 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h"
21 #include "native_client/src/trusted/validator/x86/nacl_regs.h" 21 #include "native_client/src/trusted/validator/x86/nacl_regs.h"
22 22
23 #include "native_client/src/trusted/validator/x86/decoder/ncopcode_desc_inl.c"
24 #include "native_client/src/trusted/validator/x86/x86_insts_inl.c"
25
23 #if NACL_TARGET_SUBARCH == 64 26 #if NACL_TARGET_SUBARCH == 64
24 # include "native_client/src/trusted/validator/x86/decoder/gen/nc_subregs_64.h" 27 # include "native_client/src/trusted/validator/x86/decoder/gen/nc_subregs_64.h"
25 #else 28 #else
26 # include "native_client/src/trusted/validator/x86/decoder/gen/nc_subregs_32.h" 29 # include "native_client/src/trusted/validator/x86/decoder/gen/nc_subregs_32.h"
27 #endif 30 #endif
28 31
29 /* To turn on debugging of instruction decoding, change value of 32 /* To turn on debugging of instruction decoding, change value of
30 * DEBUGGING to 1. 33 * DEBUGGING to 1.
31 */ 34 */
32 #define DEBUGGING 0 35 #define DEBUGGING 0
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 return RegGS; 81 return RegGS;
79 default: 82 default:
80 break; 83 break;
81 } 84 }
82 } 85 }
83 } 86 }
84 return reg_default; 87 return reg_default;
85 } 88 }
86 89
87 /* Return the segment register to use if DS is the default. */ 90 /* Return the segment register to use if DS is the default. */
88 static NaClOpKind NaClGetDsSegmentReg(NaClInstState* state) { 91 static INLINE NaClOpKind NaClGetDsSegmentReg(NaClInstState* state) {
89 return NaClGetSegmentPrefixReg(state, RegDS); 92 return NaClGetSegmentPrefixReg(state, RegDS);
90 } 93 }
91 94
92 /* Return the segment register to use if ES is the default. */ 95 /* Return the segment register to use if ES is the default. */
93 static NaClOpKind NaClGetEsSegmentReg(NaClInstState* state) { 96 static INLINE NaClOpKind NaClGetEsSegmentReg(NaClInstState* state) {
94 return NaClGetSegmentPrefixReg(state, RegES); 97 return NaClGetSegmentPrefixReg(state, RegES);
95 } 98 }
96 99
97 /* Append the given expression node onto the given vector of expression 100 /* Append the given expression node onto the given vector of expression
98 * nodes. Returns the appended expression node. 101 * nodes. Returns the appended expression node.
99 */ 102 */
100 static NaClExp* NaClAppendExp(NaClExpKind kind, 103 static INLINE NaClExp* NaClAppendExp(NaClExpKind kind,
101 int32_t value, 104 int32_t value,
102 NaClExpFlags flags, 105 NaClExpFlags flags,
103 NaClExpVector* vector) { 106 NaClExpVector* vector) {
104 NaClExp* node; 107 NaClExp* node;
105 assert(vector->number_expr_nodes < NACL_MAX_EXPS); 108 assert(vector->number_expr_nodes < NACL_MAX_EXPS);
106 node = &vector->node[vector->number_expr_nodes++]; 109 node = &vector->node[vector->number_expr_nodes++];
107 node->kind = kind; 110 node->kind = kind;
108 node->value = value; 111 node->value = value;
109 node->flags = flags; 112 node->flags = flags;
110 return node; 113 return node;
111 } 114 }
112 115
113 /* Report the given message and quit because we don't know 116 /* Report the given message and quit because we don't know
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 } 159 }
157 NaClFatal("Unable to determine segment regsiter from instruction name", 160 NaClFatal("Unable to determine segment regsiter from instruction name",
158 state); 161 state);
159 /* NOT REACHED */ 162 /* NOT REACHED */
160 return RegUnknown; 163 return RegUnknown;
161 } 164 }
162 165
163 /* Append the given constant onto the given vector of expression 166 /* Append the given constant onto the given vector of expression
164 * nodes. Returns the appended expression node. 167 * nodes. Returns the appended expression node.
165 */ 168 */
166 static NaClExp* NaClAppendConst(uint64_t value, NaClExpFlags flags, 169 static INLINE NaClExp* NaClAppendConst(uint64_t value, NaClExpFlags flags,
167 NaClExpVector* vector) { 170 NaClExpVector* vector) {
168 uint32_t val1; 171 uint32_t val1;
169 uint32_t val2; 172 uint32_t val2;
170 DEBUG( 173 DEBUG(
171 NaClLog(LOG_INFO, "Append constant %"NACL_PRIx64" : ", value); 174 NaClLog(LOG_INFO, "Append constant %"NACL_PRIx64" : ", value);
172 NaClPrintExpFlags(NaClLogGetGio(), flags); 175 NaClPrintExpFlags(NaClLogGetGio(), flags);
173 gprintf(NaClLogGetGio(), "\n")); 176 gprintf(NaClLogGetGio(), "\n"));
174 NaClSplitExpConstant(value, &val1, &val2); 177 NaClSplitExpConstant(value, &val1, &val2);
175 if (val2 == 0) { 178 if (val2 == 0) {
176 return NaClAppendExp(ExprConstant, val1, flags, vector); 179 return NaClAppendExp(ExprConstant, val1, flags, vector);
177 } else { 180 } else {
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 case RegR15: 463 case RegR15:
461 return NACL_EFLAG(ExprSize64); 464 return NACL_EFLAG(ExprSize64);
462 default: 465 default:
463 return 0; 466 return 0;
464 } 467 }
465 } 468 }
466 469
467 /* Appends the given kind of register onto the vector of expression nodes. 470 /* Appends the given kind of register onto the vector of expression nodes.
468 * Returns the appended register. 471 * Returns the appended register.
469 */ 472 */
470 static NaClExp* NaClAppendReg(NaClOpKind r, NaClExpVector* vector) { 473 static INLINE NaClExp* NaClAppendReg(NaClOpKind r, NaClExpVector* vector) {
471 NaClExp* node; 474 NaClExp* node;
472 DEBUG(NaClLog(LOG_INFO, "append register %s\n", NaClOpKindName(r))); 475 DEBUG(NaClLog(LOG_INFO, "append register %s\n", NaClOpKindName(r)));
473 node = NaClAppendExp(ExprRegister, r, NaClGetRegSize(r), vector); 476 node = NaClAppendExp(ExprRegister, r, NaClGetRegSize(r), vector);
474 DEBUG(NaClExpVectorPrint(NaClLogGetGio(), vector)); 477 DEBUG(NaClExpVectorPrint(NaClLogGetGio(), vector));
475 return node; 478 return node;
476 } 479 }
477 480
478 /* Given the given register kind, and the corresponding index, append 481 /* Given the given register kind, and the corresponding index, append
479 * the appropriate register onto the vector of expression nodes. 482 * the appropriate register onto the vector of expression nodes.
480 * Returns the appended register 483 * Returns the appended register
481 */ 484 */
482 static NaClExp* NaClAppendRegKind(NaClInstState* state, 485 static INLINE NaClExp* NaClAppendRegKind(NaClInstState* state,
483 NaClRegKind kind, int reg_index) { 486 NaClRegKind kind, int reg_index) {
484 DEBUG(NaClLog(LOG_INFO, "NaClAppendRegKind(%d, %d) = %s\n", 487 DEBUG(NaClLog(LOG_INFO, "NaClAppendRegKind(%d, %d) = %s\n",
485 (int) kind, reg_index, NaClRegKindName(kind))); 488 (int) kind, reg_index, NaClRegKindName(kind)));
486 return NaClAppendReg(NaClLookupReg(state, kind, reg_index), &state->nodes); 489 return NaClAppendReg(NaClLookupReg(state, kind, reg_index), &state->nodes);
487 } 490 }
488 491
489 /* Given an operand of the corresponding opcode instruction of the 492 /* Given an operand of the corresponding opcode instruction of the
490 * given state, return what kind of register should be used, based 493 * given state, return what kind of register should be used, based
491 * on the operand size. 494 * on the operand size.
492 */ 495 */
493 static NaClRegKind NaClExtractOpRegKind(NaClInstState* state, 496 static NaClRegKind NaClExtractOpRegKind(NaClInstState* state,
(...skipping 25 matching lines...) Expand all
519 return RegSize64; 522 return RegSize64;
520 } else { 523 } else {
521 return RegSize32; 524 return RegSize32;
522 } 525 }
523 } 526 }
524 } 527 }
525 528
526 /* Given an address of the corresponding opcode instruction of the 529 /* Given an address of the corresponding opcode instruction of the
527 * given state, return what kind of register should be used. 530 * given state, return what kind of register should be used.
528 */ 531 */
529 static NaClRegKind NaClExtractAddressRegKind(NaClInstState* state) { 532 static INLINE NaClRegKind NaClExtractAddressRegKind(NaClInstState* state) {
530 if (state->address_size == 16) { 533 if (state->address_size == 16) {
531 return RegSize16; 534 return RegSize16;
532 } else if (state->address_size == 64) { 535 } else if (state->address_size == 64) {
533 return RegSize64; 536 return RegSize64;
534 } else { 537 } else {
535 return RegSize32; 538 return RegSize32;
536 } 539 }
537 } 540 }
538 541
539 /* Given we want to translate an operand (of the form G_Operand), 542 /* Given we want to translate an operand (of the form G_Operand),
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 RegES, 605 RegES,
603 RegCS, 606 RegCS,
604 RegSS, 607 RegSS,
605 RegDS, 608 RegDS,
606 RegFS, 609 RegFS,
607 RegGS, 610 RegGS,
608 /* These should not happen. */ 611 /* These should not happen. */
609 RegUnknown, 612 RegUnknown,
610 RegUnknown 613 RegUnknown
611 }; 614 };
612 return NaClAppendReg(seg[modrm_reg(state->modrm)], &state->nodes); 615 return NaClAppendReg(seg[modrm_regInline(state->modrm)], &state->nodes);
613 } 616 }
614 617
615 /* For the given instruction state, and the corresponding 3-bit specification 618 /* For the given instruction state, and the corresponding 3-bit specification
616 * of a register, update it to a 4-bit specification, based on the REX.R bit. 619 * of a register, update it to a 4-bit specification, based on the REX.R bit.
617 */ 620 */
618 static int NaClGetRexRReg(NaClInstState* state, int reg) { 621 static INLINE int NaClGetRexRReg(NaClInstState* state, int reg) {
619 DEBUG(NaClLog(LOG_INFO, "Get GenRexRRegister %d\n", reg)); 622 DEBUG(NaClLog(LOG_INFO, "Get GenRexRRegister %d\n", reg));
620 if (NACL_TARGET_SUBARCH == 64 && (state->rexprefix & 0x4)) { 623 if (NACL_TARGET_SUBARCH == 64 && (state->rexprefix & 0x4)) {
621 reg += 8; 624 reg += 8;
622 } 625 }
623 return reg; 626 return reg;
624 } 627 }
625 628
626 /* For the given instruction state, and the corresponding 3-bit specification 629 /* For the given instruction state, and the corresponding 3-bit specification
627 * of a register, update it to a 4-bit specification, based on the REX.X bit. 630 * of a register, update it to a 4-bit specification, based on the REX.X bit.
628 */ 631 */
629 static int NaClGetRexXReg(NaClInstState* state, int reg) { 632 static INLINE int NaClGetRexXReg(NaClInstState* state, int reg) {
630 DEBUG(NaClLog(LOG_INFO, "Get GenRexXRegister\n")); 633 DEBUG(NaClLog(LOG_INFO, "Get GenRexXRegister\n"));
631 if (NACL_TARGET_SUBARCH == 64 && (state->rexprefix & 0x2)) { 634 if (NACL_TARGET_SUBARCH == 64 && (state->rexprefix & 0x2)) {
632 reg += 8; 635 reg += 8;
633 } 636 }
634 return reg; 637 return reg;
635 } 638 }
636 639
637 /* For the given instruction state, and the corresponding 3-bit specification 640 /* For the given instruction state, and the corresponding 3-bit specification
638 * of a register, update it to a 4-bit specification, based on the REX.B bit. 641 * of a register, update it to a 4-bit specification, based on the REX.B bit.
639 */ 642 */
640 static int NaClGetRexBReg(NaClInstState* state, int reg) { 643 static INLINE int NaClGetRexBReg(NaClInstState* state, int reg) {
641 DEBUG(NaClLog(LOG_INFO, "Get GenRexBRegister\n")); 644 DEBUG(NaClLog(LOG_INFO, "Get GenRexBRegister\n"));
642 if (NACL_TARGET_SUBARCH == 64 && (state->rexprefix & 0x1)) { 645 if (NACL_TARGET_SUBARCH == 64 && (state->rexprefix & 0x1)) {
643 DEBUG(NaClLog(LOG_INFO, "rexprefix == %02x\n", state->rexprefix)); 646 DEBUG(NaClLog(LOG_INFO, "rexprefix == %02x\n", state->rexprefix));
644 reg += 8; 647 reg += 8;
645 } 648 }
646 return reg; 649 return reg;
647 } 650 }
648 651
649 /* Return the general purpose register associated with the modrm.reg 652 /* Return the general purpose register associated with the modrm.reg
650 * field. 653 * field.
651 */ 654 */
652 static int NaClGetGenRegRegister(NaClInstState* state) { 655 static INLINE int NaClGetGenRegRegister(NaClInstState* state) {
653 DEBUG(NaClLog(LOG_INFO, "Get GenRegRegister\n")); 656 DEBUG(NaClLog(LOG_INFO, "Get GenRegRegister\n"));
654 return NaClGetRexRReg(state, modrm_reg(state->modrm)); 657 return NaClGetRexRReg(state, modrm_regInline(state->modrm));
655 } 658 }
656 659
657 /* Return the general purpose register associated with the modrm.rm 660 /* Return the general purpose register associated with the modrm.rm
658 * field. 661 * field.
659 */ 662 */
660 static int NaClGetGenRmRegister(NaClInstState* state) { 663 static INLINE int NaClGetGenRmRegister(NaClInstState* state) {
661 DEBUG(NaClLog(LOG_INFO, "Get GenRmRegister\n")); 664 DEBUG(NaClLog(LOG_INFO, "Get GenRmRegister\n"));
662 return NaClGetRexBReg(state, modrm_rm(state->modrm)); 665 return NaClGetRexBReg(state, modrm_rmInline(state->modrm));
663 } 666 }
664 667
665 /* Get the register index from the difference of the opcode, and 668 /* Get the register index from the difference of the opcode, and
666 * its opcode base. 669 * its opcode base.
667 */ 670 */
668 static NaClExp* NaClAppendOpcodeBaseReg( 671 static NaClExp* NaClAppendOpcodeBaseReg(
669 NaClInstState* state, const NaClOp* operand) { 672 NaClInstState* state, const NaClOp* operand) {
670 int reg_index; 673 int reg_index;
671 reg_index = NaClGetOpcodePlusR(state->inst->opcode_ext); 674 reg_index = NaClGetOpcodePlusR(state->inst->opcode_ext);
672 assert(reg_index >= 0 && reg_index < 8); 675 assert(reg_index >= 0 && reg_index < 8);
(...skipping 12 matching lines...) Expand all
685 DEBUG(NaClLog(LOG_INFO, "Translate opcode base register %d\n", reg_index)); 688 DEBUG(NaClLog(LOG_INFO, "Translate opcode base register %d\n", reg_index));
686 return NaClAppendReg(RegST0 + reg_index, &state->nodes); 689 return NaClAppendReg(RegST0 + reg_index, &state->nodes);
687 } 690 }
688 691
689 /* Model the extraction of a displacement value and the associated flags. */ 692 /* Model the extraction of a displacement value and the associated flags. */
690 typedef struct NaClDisplacement { 693 typedef struct NaClDisplacement {
691 uint64_t value; 694 uint64_t value;
692 NaClExpFlags flags; 695 NaClExpFlags flags;
693 } NaClDisplacement; 696 } NaClDisplacement;
694 697
695 static void NaClInitializeDisplacement(uint64_t value, NaClExpFlags flags, 698 static INLINE void NaClInitializeDisplacement(
696 NaClDisplacement* displacement) { 699 uint64_t value, NaClExpFlags flags,
700 NaClDisplacement* displacement) {
697 displacement->value = value; 701 displacement->value = value;
698 displacement->flags = flags; 702 displacement->flags = flags;
699 } 703 }
700 704
701 /* Extract the binary value from the specified bytes of the instruction. */ 705 /* Extract the binary value from the specified bytes of the instruction. */
702 uint64_t NaClExtractUnsignedBinaryValue(NaClInstState* state, 706 uint64_t NaClExtractUnsignedBinaryValue(NaClInstState* state,
703 int start_byte, int num_bytes) { 707 int start_byte, int num_bytes) {
704 int i; 708 int i;
705 uint64_t value = 0; 709 uint64_t value = 0;
706 for (i = 0; i < num_bytes; ++i) { 710 for (i = 0; i < num_bytes; ++i) {
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 DEBUG(NaClLog(LOG_INFO, "finished appending memory offset:\n")); 988 DEBUG(NaClLog(LOG_INFO, "finished appending memory offset:\n"));
985 DEBUG(NaClExpVectorPrint(NaClLogGetGio(), &state->nodes)); 989 DEBUG(NaClExpVectorPrint(NaClLogGetGio(), &state->nodes));
986 return root; 990 return root;
987 } 991 }
988 992
989 /* Extract the base register from the SIB byte. */ 993 /* Extract the base register from the SIB byte. */
990 static NaClOpKind NaClGetSibBase(NaClInstState* state) { 994 static NaClOpKind NaClGetSibBase(NaClInstState* state) {
991 int base = sib_base(state->sib); 995 int base = sib_base(state->sib);
992 NaClOpKind base_reg = RegUnknown; 996 NaClOpKind base_reg = RegUnknown;
993 if (0x5 == base) { 997 if (0x5 == base) {
994 switch (modrm_mod(state->modrm)) { 998 switch (modrm_modInline(state->modrm)) {
995 case 0: 999 case 0:
996 break; 1000 break;
997 case 1: 1001 case 1:
998 case 2: 1002 case 2:
999 if (NACL_TARGET_SUBARCH == 64) { 1003 if (NACL_TARGET_SUBARCH == 64) {
1000 if (state->rexprefix & 0x1) { 1004 if (state->rexprefix & 0x1) {
1001 base_reg = RegR13; 1005 base_reg = RegR13;
1002 } else { 1006 } else {
1003 base_reg = RegRBP; 1007 base_reg = RegRBP;
1004 } 1008 }
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1110 1114
1111 /* Get the Effective address in the mod/rm byte, if the modrm.mod field 1115 /* Get the Effective address in the mod/rm byte, if the modrm.mod field
1112 * is 00, and append it to the vector of expression nodes. Operand is 1116 * is 00, and append it to the vector of expression nodes. Operand is
1113 * the corresponding operand of the opcode associated with the instruction 1117 * the corresponding operand of the opcode associated with the instruction
1114 * of the given state that corresponds to the effective address. Returns 1118 * of the given state that corresponds to the effective address. Returns
1115 * the root of the appended effective address. 1119 * the root of the appended effective address.
1116 */ 1120 */
1117 static NaClExp* NaClAppendMod00EffectiveAddress( 1121 static NaClExp* NaClAppendMod00EffectiveAddress(
1118 NaClInstState* state, const NaClOp* operand) { 1122 NaClInstState* state, const NaClOp* operand) {
1119 DEBUG(NaClLog(LOG_INFO, "Translate modrm(%02x).mod == 00\n", state->modrm)); 1123 DEBUG(NaClLog(LOG_INFO, "Translate modrm(%02x).mod == 00\n", state->modrm));
1120 switch (modrm_rm(state->modrm)) { 1124 switch (modrm_rmInline(state->modrm)) {
1121 case 4: 1125 case 4:
1122 return NaClAppendSib(state); 1126 return NaClAppendSib(state);
1123 case 5: 1127 case 5:
1124 if (NACL_TARGET_SUBARCH == 64) { 1128 if (NACL_TARGET_SUBARCH == 64) {
1125 NaClDisplacement displacement; 1129 NaClDisplacement displacement;
1126 NaClExtractDisplacement(state, &displacement, 1130 NaClExtractDisplacement(state, &displacement,
1127 NACL_EFLAG(ExprSignedHex)); 1131 NACL_EFLAG(ExprSignedHex));
1128 return NaClAppendMemoryOffset(state, 1132 return NaClAppendMemoryOffset(state,
1129 RegRIP, 1133 RegRIP,
1130 RegUnknown, 1134 RegUnknown,
(...skipping 21 matching lines...) Expand all
1152 1156
1153 /* Get the Effective address in the mod/rm byte, if the modrm.mod field 1157 /* Get the Effective address in the mod/rm byte, if the modrm.mod field
1154 * is 01, and append it to the vector of expression nodes. Operand is 1158 * is 01, and append it to the vector of expression nodes. Operand is
1155 * the corresponding operand of the opcode associated with the instruction 1159 * the corresponding operand of the opcode associated with the instruction
1156 * of the given state that corresponds to the effective address. Returns 1160 * of the given state that corresponds to the effective address. Returns
1157 * the root of the appended effective address. 1161 * the root of the appended effective address.
1158 */ 1162 */
1159 static NaClExp* NaClAppendMod01EffectiveAddress( 1163 static NaClExp* NaClAppendMod01EffectiveAddress(
1160 NaClInstState* state, const NaClOp* operand) { 1164 NaClInstState* state, const NaClOp* operand) {
1161 DEBUG(NaClLog(LOG_INFO, "Translate modrm(%02x).mod == 01\n", state->modrm)); 1165 DEBUG(NaClLog(LOG_INFO, "Translate modrm(%02x).mod == 01\n", state->modrm));
1162 if (4 == modrm_rm(state->modrm)) { 1166 if (4 == modrm_rmInline(state->modrm)) {
1163 return NaClAppendSib(state); 1167 return NaClAppendSib(state);
1164 } else { 1168 } else {
1165 NaClDisplacement displacement; 1169 NaClDisplacement displacement;
1166 NaClExtractDisplacement(state, &displacement, NACL_EFLAG(ExprSignedHex)); 1170 NaClExtractDisplacement(state, &displacement, NACL_EFLAG(ExprSignedHex));
1167 return NaClAppendMemoryOffset(state, 1171 return NaClAppendMemoryOffset(state,
1168 NaClLookupReg( 1172 NaClLookupReg(
1169 state, 1173 state,
1170 NaClExtractAddressRegKind(state), 1174 NaClExtractAddressRegKind(state),
1171 NaClGetGenRmRegister(state)), 1175 NaClGetGenRmRegister(state)),
1172 RegUnknown, 1176 RegUnknown,
1173 1, 1177 1,
1174 &displacement); 1178 &displacement);
1175 } 1179 }
1176 } 1180 }
1177 1181
1178 /* Get the Effective address in the mod/rm byte, if the modrm.mod field 1182 /* Get the Effective address in the mod/rm byte, if the modrm.mod field
1179 * is 10, and append it to the vector of expression nodes. Operand is 1183 * is 10, and append it to the vector of expression nodes. Operand is
1180 * the corresponding operand of the opcode associated with the instruction 1184 * the corresponding operand of the opcode associated with the instruction
1181 * of the given state that corresponds to the effective address. Returns 1185 * of the given state that corresponds to the effective address. Returns
1182 * the root of the appended effective address. 1186 * the root of the appended effective address.
1183 */ 1187 */
1184 static NaClExp* NaClAppendMod10EffectiveAddress( 1188 static NaClExp* NaClAppendMod10EffectiveAddress(
1185 NaClInstState* state, const NaClOp* operand) { 1189 NaClInstState* state, const NaClOp* operand) {
1186 DEBUG(NaClLog(LOG_INFO, "Translate modrm(%02x).mod == 10\n", state->modrm)); 1190 DEBUG(NaClLog(LOG_INFO, "Translate modrm(%02x).mod == 10\n", state->modrm));
1187 if (4 == modrm_rm(state->modrm)) { 1191 if (4 == modrm_rmInline(state->modrm)) {
1188 return NaClAppendSib(state); 1192 return NaClAppendSib(state);
1189 } else { 1193 } else {
1190 NaClDisplacement displacement; 1194 NaClDisplacement displacement;
1191 NaClOpKind base = 1195 NaClOpKind base =
1192 NaClLookupReg(state, 1196 NaClLookupReg(state,
1193 NaClExtractAddressRegKind(state), 1197 NaClExtractAddressRegKind(state),
1194 NaClGetGenRmRegister(state)); 1198 NaClGetGenRmRegister(state));
1195 NaClExtractDisplacement(state, &displacement, NACL_EFLAG(ExprSignedHex)); 1199 NaClExtractDisplacement(state, &displacement, NACL_EFLAG(ExprSignedHex));
1196 return NaClAppendMemoryOffset(state, base, RegUnknown, 1, &displacement); 1200 return NaClAppendMemoryOffset(state, base, RegUnknown, 1, &displacement);
1197 } 1201 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1244 default: 1248 default:
1245 return NaClFatal("can't translate register group: address size not valid", 1249 return NaClFatal("can't translate register group: address size not valid",
1246 state); 1250 state);
1247 } 1251 }
1248 } 1252 }
1249 1253
1250 /* Compute the effect address using the Mod/Rm and SIB bytes. */ 1254 /* Compute the effect address using the Mod/Rm and SIB bytes. */
1251 static NaClExp* NaClAppendEffectiveAddress( 1255 static NaClExp* NaClAppendEffectiveAddress(
1252 NaClInstState* state, const NaClOp* operand, 1256 NaClInstState* state, const NaClOp* operand,
1253 NaClModRmRegKind modrm_reg_kind) { 1257 NaClModRmRegKind modrm_reg_kind) {
1254 switch(modrm_mod(state->modrm)) { 1258 switch(modrm_modInline(state->modrm)) {
1255 case 0: 1259 case 0:
1256 return NaClAppendMod00EffectiveAddress(state, operand); 1260 return NaClAppendMod00EffectiveAddress(state, operand);
1257 case 1: 1261 case 1:
1258 return NaClAppendMod01EffectiveAddress(state, operand); 1262 return NaClAppendMod01EffectiveAddress(state, operand);
1259 case 2: 1263 case 2:
1260 return NaClAppendMod10EffectiveAddress(state, operand); 1264 return NaClAppendMod10EffectiveAddress(state, operand);
1261 case 3: 1265 case 3:
1262 return NaClAppendMod11EffectiveAddress(state, operand, modrm_reg_kind); 1266 return NaClAppendMod11EffectiveAddress(state, operand, modrm_reg_kind);
1263 default: 1267 default:
1264 break; 1268 break;
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
1556 if (operand->flags & NACL_OPFLAG(OpUse)) { 1560 if (operand->flags & NACL_OPFLAG(OpUse)) {
1557 node->flags |= NACL_EFLAG(ExprUsed); 1561 node->flags |= NACL_EFLAG(ExprUsed);
1558 } 1562 }
1559 if (operand->flags & NACL_OPFLAG(OpAddress)) { 1563 if (operand->flags & NACL_OPFLAG(OpAddress)) {
1560 node->flags |= NACL_EFLAG(ExprAddress); 1564 node->flags |= NACL_EFLAG(ExprAddress);
1561 } 1565 }
1562 return node; 1566 return node;
1563 } 1567 }
1564 1568
1565 void NaClBuildExpVector(struct NaClInstState* state) { 1569 void NaClBuildExpVector(struct NaClInstState* state) {
1566 int i; 1570 uint8_t i;
1571 uint8_t num_ops;
1567 DEBUG(NaClLog(LOG_INFO, 1572 DEBUG(NaClLog(LOG_INFO,
1568 "building expression vector for pc = %"NACL_PRIxNaClPcAddress 1573 "building expression vector for pc = %"NACL_PRIxNaClPcAddress
1569 ":\n", 1574 ":\n",
1570 NaClInstStateVpc(state))); 1575 NaClInstStateVpc(state)));
1571 for (i = 0; i < state->inst->num_operands; i++) { 1576 num_ops = NaClGetInstNumberOperandsInline(state->inst);
1577 for (i = 0; i < num_ops; i++) {
1572 NaClExp* n; 1578 NaClExp* n;
1573 const NaClOp* op = NaClGetInstOperand(state->decoder_tables, 1579 const NaClOp* op = NaClGetInstOperandInline(state->decoder_tables,
1574 state->inst, i); 1580 state->inst, i);
1575 DEBUG(NaClLog(LOG_INFO, "translating operand %d:\n", i)); 1581 DEBUG(NaClLog(LOG_INFO, "translating operand %d:\n", i));
1576 n = NaClAppendExp(OperandReference, i, 0, &state->nodes); 1582 n = NaClAppendExp(OperandReference, i, 0, &state->nodes);
1577 if (op->flags & NACL_OPFLAG(OpImplicit)) { 1583 if (op->flags & NACL_OPFLAG(OpImplicit)) {
1578 n->flags |= NACL_EFLAG(ExprImplicit); 1584 n->flags |= NACL_EFLAG(ExprImplicit);
1579 } 1585 }
1580 NaClAddOpSetUse(NaClAppendOperand(state, op), op); 1586 NaClAddOpSetUse(NaClAppendOperand(state, op), op);
1581 DEBUG(NaClExpVectorPrint(NaClLogGetGio(), &state->nodes)); 1587 DEBUG(NaClExpVectorPrint(NaClLogGetGio(), &state->nodes));
1582 } 1588 }
1583 } 1589 }
OLDNEW
« no previous file with comments | « src/trusted/validator/x86/decoder/nc_inst_state_statics.c ('k') | src/trusted/validator/x86/decoder/ncop_exps.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698