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

Side by Side Diff: src/trusted/validator/x86/decoder/nc_inst_state_statics.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 * This file contains includes, static functions, and constants that are used 8 * This file contains includes, static functions, and constants that are used
9 * in nc_inst_state.c, but have been factored out and put into this file, so 9 * in nc_inst_state.c, but have been factored out and put into this file, so
10 * that we can test them. That is, to allow nc_inst_state.c and 10 * that we can test them. That is, to allow nc_inst_state.c and
11 * nc_inst_state_Tests.cc to use them. 11 * nc_inst_state_Tests.cc to use them.
12 */ 12 */
13 13
14 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_DECODER_NC_INST_STATE_STATICS_C_ _ 14 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_DECODER_NC_INST_STATE_STATICS_C_ _
15 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_DECODER_NC_INST_STATE_STATICS_C_ _ 15 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_DECODER_NC_INST_STATE_STATICS_C_ _
16 16
17 #include <stdio.h> 17 #include <stdio.h>
18 #include <assert.h> 18 #include <assert.h>
19 #include "native_client/src/shared/platform/nacl_log.h" 19 #include "native_client/src/shared/platform/nacl_log.h"
20 #include "native_client/src/shared/utils/debugging.h" 20 #include "native_client/src/shared/utils/debugging.h"
21 #include "native_client/src/trusted/validator/x86/decoder/nc_decode_tables.h" 21 #include "native_client/src/trusted/validator/x86/decoder/nc_decode_tables.h"
22 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_iter.h" 22 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_iter.h"
23 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal .h" 23 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal .h"
24 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_trans.h" 24 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_trans.h"
25 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h" 25 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h"
26 #include "native_client/src/trusted/validator/x86/decoder/ncopcode_desc.h" 26 #include "native_client/src/trusted/validator/x86/decoder/ncopcode_desc.h"
27 #include "native_client/src/trusted/validator/x86/nc_segment.h" 27 #include "native_client/src/trusted/validator/x86/nc_segment.h"
28 #include "native_client/src/trusted/validator/x86/x86_insts_inl.h"
28 29
29 EXTERN_C_BEGIN 30 EXTERN_C_BEGIN
30 31
31 /* Given the current location of the instruction iterator, initialize 32 /* Given the current location of the instruction iterator, initialize
32 * the given state (to match). 33 * the given state (to match).
33 */ 34 */
34 static void NaClInstStateInit(NaClInstIter* iter, NaClInstState* state) { 35 static void NaClInstStateInit(NaClInstIter* iter, NaClInstState* state) {
35 NaClMemorySize limit; 36 NaClMemorySize limit;
36 NCInstBytesInit(&state->bytes); 37 NCInstBytesInit(&state->bytes);
37 state->decoder_tables = iter->decoder_tables; 38 state->decoder_tables = iter->decoder_tables;
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 /* Has modrm byte. */ 442 /* Has modrm byte. */
442 if (state->bytes.length >= state->length_limit) { 443 if (state->bytes.length >= state->length_limit) {
443 DEBUG(NaClLog(LOG_INFO, "Can't read mod/rm, no more bytes!\n")); 444 DEBUG(NaClLog(LOG_INFO, "Can't read mod/rm, no more bytes!\n"));
444 return FALSE; 445 return FALSE;
445 } 446 }
446 byte = NCInstBytesPeek(&state->bytes, 0); 447 byte = NCInstBytesPeek(&state->bytes, 0);
447 448
448 /* Note: Some instructions only allow values where the ModRm mod field 449 /* Note: Some instructions only allow values where the ModRm mod field
449 * is 0x3. Others only allow values where the ModRm mod field isn't 0x3. 450 * is 0x3. Others only allow values where the ModRm mod field isn't 0x3.
450 */ 451 */
451 if (modrm_mod(byte) == 0x3) { 452 if (modrm_modInline(byte) == 0x3) {
452 if (NaClHasBit(state->inst->flags, NACL_IFLAG(ModRmModIsnt0x3))) { 453 if (NaClHasBit(state->inst->flags, NACL_IFLAG(ModRmModIsnt0x3))) {
453 DEBUG(NaClLog(LOG_INFO, "Can't match, modrm mod field is 0x3\n")); 454 DEBUG(NaClLog(LOG_INFO, "Can't match, modrm mod field is 0x3\n"));
454 return FALSE; 455 return FALSE;
455 } 456 }
456 } else { 457 } else {
457 if (NaClHasBit(state->inst->flags, NACL_IFLAG(ModRmModIs0x3))) { 458 if (NaClHasBit(state->inst->flags, NACL_IFLAG(ModRmModIs0x3))) {
458 DEBUG(NaClLog(LOG_INFO, "Can't match, modrm mod field not 0x3\n")); 459 DEBUG(NaClLog(LOG_INFO, "Can't match, modrm mod field not 0x3\n"));
459 return FALSE; 460 return FALSE;
460 } 461 }
461 } 462 }
462 if ((NaClHasBit(state->inst->flags, NACL_IFLAG(ModRmRegSOperand))) && 463 if ((NaClHasBit(state->inst->flags, NACL_IFLAG(ModRmRegSOperand))) &&
463 (modrm_reg(byte) > 5)) { 464 (modrm_regInline(byte) > 5)) {
464 DEBUG(NaClLog(LOG_INFO, 465 DEBUG(NaClLog(LOG_INFO,
465 "Can't match, modrm reg field doesn't index segment\n")); 466 "Can't match, modrm reg field doesn't index segment\n"));
466 return FALSE; 467 return FALSE;
467 } 468 }
468 state->modrm = NCInstBytesRead(&state->bytes); 469 state->modrm = NCInstBytesRead(&state->bytes);
469 state->num_disp_bytes = 0; 470 state->num_disp_bytes = 0;
470 state->first_disp_byte = 0; 471 state->first_disp_byte = 0;
471 state->sib = 0; 472 state->sib = 0;
472 state->has_sib = FALSE; 473 state->has_sib = FALSE;
473 DEBUG(NaClLog(LOG_INFO, "consume modrm = %02"NACL_PRIx8"\n", state->modrm)); 474 DEBUG(NaClLog(LOG_INFO, "consume modrm = %02"NACL_PRIx8"\n", state->modrm));
474 475
475 /* Consume the remaining opcode value in the mod/rm byte 476 /* Consume the remaining opcode value in the mod/rm byte
476 * if applicable. 477 * if applicable.
477 */ 478 */
478 if (state->inst->flags & NACL_IFLAG(OpcodeInModRm)) { 479 if (state->inst->flags & NACL_IFLAG(OpcodeInModRm)) {
479 const NaClInst* inst = state->inst; 480 const NaClInst* inst = state->inst;
480 if (modrm_opcode(state->modrm) != 481 if (modrm_opcodeInline(state->modrm) !=
481 NaClGetOpcodeInModRm(inst->opcode_ext)) { 482 NaClGetOpcodeInModRm(inst->opcode_ext)) {
482 DEBUG( 483 DEBUG(
483 NaClLog(LOG_INFO, 484 NaClLog(LOG_INFO,
484 "Discarding, opcode in mrm byte (%02"NACL_PRIx8") " 485 "Discarding, opcode in mrm byte (%02"NACL_PRIx8") "
485 "does not match\n", 486 "does not match\n",
486 modrm_opcode(state->modrm))); 487 modrm_opcodeInline(state->modrm)));
487 return FALSE; 488 return FALSE;
488 } 489 }
489 if (state->inst->flags & NACL_IFLAG(OpcodeInModRmRm)) { 490 if (state->inst->flags & NACL_IFLAG(OpcodeInModRmRm)) {
490 if (modrm_rm(state->modrm) != 491 if (modrm_rmInline(state->modrm) !=
491 NaClGetOpcodeInModRmRm(inst->opcode_ext)) { 492 NaClGetOpcodeInModRmRm(inst->opcode_ext)) {
492 DEBUG(NaClLog(LOG_INFO, 493 DEBUG(NaClLog(LOG_INFO,
493 "Discarding, opcode in mrm rm field (%02"NACL_PRIx8") " 494 "Discarding, opcode in mrm rm field (%02"NACL_PRIx8") "
494 "does not match\n", 495 "does not match\n",
495 modrm_rm(state->modrm))); 496 modrm_rmInline(state->modrm)));
496 return FALSE; 497 return FALSE;
497 } 498 }
498 } 499 }
499 } 500 }
500 } 501 }
501 return TRUE; 502 return TRUE;
502 } 503 }
503 504
504 /* Returns true if the instruction requires a SIB bytes. */ 505 /* Returns true if the instruction requires a SIB bytes. */
505 static Bool NaClInstRequiresSib(NaClInstState* state) { 506 static Bool NaClInstRequiresSib(NaClInstState* state) {
506 /* Note: in 64-bit mode, 64-bit addressing is treated the same as 32-bit 507 /* Note: in 64-bit mode, 64-bit addressing is treated the same as 32-bit
507 * addressing. Hence, required for all but 16-bit addressing, when 508 * addressing. Hence, required for all but 16-bit addressing, when
508 * the right modrm bytes are specified. 509 * the right modrm bytes are specified.
509 */ 510 */
510 return (Bool) 511 return (Bool)
511 (NaClInstRequiresModRm(state) && (16 != state->address_size) && 512 (NaClInstRequiresModRm(state) && (16 != state->address_size) &&
512 (modrm_rm(state->modrm) == 0x04 && modrm_mod(state->modrm) != 0x3)); 513 (modrm_rmInline(state->modrm) ==
514 0x04 && modrm_modInline(state->modrm) != 0x3));
513 } 515 }
514 516
515 /* Consume the SIB byte of the instruction, if applicable. Aborts the pattern 517 /* Consume the SIB byte of the instruction, if applicable. Aborts the pattern
516 * match if any problems are found. 518 * match if any problems are found.
517 */ 519 */
518 static Bool NaClConsumeSib(NaClInstState* state) { 520 static Bool NaClConsumeSib(NaClInstState* state) {
519 /* First check that the opcode (instruction) pattern specifies that 521 /* First check that the opcode (instruction) pattern specifies that
520 * a SIB byte is needed, and that reading it will not walk past 522 * a SIB byte is needed, and that reading it will not walk past
521 * the end of the code segment. 523 * the end of the code segment.
522 */ 524 */
523 state->sib = 0; 525 state->sib = 0;
524 state->has_sib = NaClInstRequiresSib(state); 526 state->has_sib = NaClInstRequiresSib(state);
525 DEBUG(NaClLog(LOG_INFO, "has sib = %d\n", (int) state->has_sib)); 527 DEBUG(NaClLog(LOG_INFO, "has sib = %d\n", (int) state->has_sib));
526 if (state->has_sib) { 528 if (state->has_sib) {
527 if (state->bytes.length >= state->length_limit) { 529 if (state->bytes.length >= state->length_limit) {
528 DEBUG(NaClLog(LOG_INFO, "Can't consume sib, no more bytes!\n")); 530 DEBUG(NaClLog(LOG_INFO, "Can't consume sib, no more bytes!\n"));
529 return FALSE; 531 return FALSE;
530 } 532 }
531 /* Read the SIB byte and record. */ 533 /* Read the SIB byte and record. */
532 state->sib = NCInstBytesRead(&state->bytes); 534 state->sib = NCInstBytesRead(&state->bytes);
533 DEBUG(NaClLog(LOG_INFO, "sib = %02"NACL_PRIx8"\n", state->sib)); 535 DEBUG(NaClLog(LOG_INFO, "sib = %02"NACL_PRIx8"\n", state->sib));
534 if (sib_base(state->sib) == 0x05 && modrm_mod(state->modrm) > 2) { 536 if (sib_base(state->sib) == 0x05 && modrm_modInline(state->modrm) > 2) {
535 DEBUG(NaClLog(LOG_INFO, 537 DEBUG(NaClLog(LOG_INFO,
536 "Sib byte implies modrm.mod field <= 2, match fails\n")); 538 "Sib byte implies modrm.mod field <= 2, match fails\n"));
537 return FALSE; 539 return FALSE;
538 } 540 }
539 } 541 }
540 return TRUE; 542 return TRUE;
541 } 543 }
542 544
543 static int NaClGetNumDispBytes(NaClInstState* state) { 545 static int NaClGetNumDispBytes(NaClInstState* state) {
544 if (NaClInstRequiresModRm(state)) { 546 if (NaClInstRequiresModRm(state)) {
545 if (16 == state->address_size) { 547 if (16 == state->address_size) {
546 /* Corresponding to table 2-1 of the Intel manual. */ 548 /* Corresponding to table 2-1 of the Intel manual. */
547 switch (modrm_mod(state->modrm)) { 549 switch (modrm_modInline(state->modrm)) {
548 case 0x0: 550 case 0x0:
549 if (modrm_rm(state->modrm) == 0x06) { 551 if (modrm_rmInline(state->modrm) == 0x06) {
550 return 4; /* disp16 */ 552 return 4; /* disp16 */
551 } 553 }
552 break; 554 break;
553 case 0x1: 555 case 0x1:
554 return 1; /* disp8 */ 556 return 1; /* disp8 */
555 case 0x2: 557 case 0x2:
556 return 2; /* disp16 */ 558 return 2; /* disp16 */
557 default: 559 default:
558 break; 560 break;
559 } 561 }
560 } else { 562 } else {
561 /* Note: in 64-bit mode, 64-bit addressing is treated the same as 32-bit 563 /* Note: in 64-bit mode, 64-bit addressing is treated the same as 32-bit
562 * addressing. Hence, this section covers the 32-bit addressing. 564 * addressing. Hence, this section covers the 32-bit addressing.
563 */ 565 */
564 switch(modrm_mod(state->modrm)) { 566 switch(modrm_modInline(state->modrm)) {
565 case 0x0: 567 case 0x0:
566 if (modrm_rm(state->modrm) == 0x05) { 568 if (modrm_rmInline(state->modrm) == 0x05) {
567 return 4; /* disp32 */ 569 return 4; /* disp32 */
568 } else if (state->has_sib && sib_base(state->sib) == 0x5) { 570 } else if (state->has_sib && sib_base(state->sib) == 0x5) {
569 return 4; 571 return 4;
570 } 572 }
571 break; 573 break;
572 case 0x1: 574 case 0x1:
573 return 1; /* disp8 */ 575 return 1; /* disp8 */
574 case 0x2: 576 case 0x2:
575 return 4; /* disp32 */ 577 return 4; /* disp32 */
576 default: 578 default:
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 state->inst = matching_inst; 921 state->inst = matching_inst;
920 NCInstBytesReadBytes(matching_length, &state->bytes); 922 NCInstBytesReadBytes(matching_length, &state->bytes);
921 DEBUG(NaClLog(LOG_INFO, "matched inst sequence [%d]!\n", matching_length)); 923 DEBUG(NaClLog(LOG_INFO, "matched inst sequence [%d]!\n", matching_length));
922 return TRUE; 924 return TRUE;
923 } 925 }
924 } 926 }
925 927
926 EXTERN_C_END 928 EXTERN_C_END
927 929
928 #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_DECODER_NC_INST_STATE_STATIC S_C__ */ 930 #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_DECODER_NC_INST_STATE_STATIC S_C__ */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698