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

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

Powered by Google App Engine
This is Rietveld 408576698