| Index: src/trusted/validator/x86/decoder/generator/nc_compress.c
|
| diff --git a/src/trusted/validator/x86/decoder/generator/nc_compress.c b/src/trusted/validator/x86/decoder/generator/nc_compress.c
|
| deleted file mode 100644
|
| index 10091cb6b4e2c26e916deb667e7b30cec25babc6..0000000000000000000000000000000000000000
|
| --- a/src/trusted/validator/x86/decoder/generator/nc_compress.c
|
| +++ /dev/null
|
| @@ -1,322 +0,0 @@
|
| -/*
|
| - * Copyright (c) 2011 The Native Client Authors. All rights reserved.
|
| - * Use of this source code is governed by a BSD-style license that can be
|
| - * found in the LICENSE file.
|
| - */
|
| -
|
| -/*
|
| - * Compresses the tables for the table generator.
|
| - */
|
| -
|
| -#ifndef NACL_TRUSTED_BUT_NOT_TCB
|
| -#error("This file is not meant for use in the TCB")
|
| -#endif
|
| -
|
| -#include <stdio.h>
|
| -#include <stdlib.h>
|
| -#include <assert.h>
|
| -#include <string.h>
|
| -
|
| -#include "native_client/src/trusted/validator/x86/decoder/generator/nc_compress.h"
|
| -
|
| -#include "native_client/src/include/portability.h"
|
| -#include "native_client/src/include/portability_io.h"
|
| -#include "native_client/src/shared/utils/flags.h"
|
| -#include "native_client/src/shared/platform/nacl_log.h"
|
| -#include "native_client/src/trusted/validator/x86/x86_insts.h"
|
| -#include "native_client/src/trusted/validator/x86/decoder/generator/nacl_regsgen.h"
|
| -#include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_forms.h"
|
| -#include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_st.h"
|
| -
|
| -/* To turn on debugging of instruction decoding, change value of
|
| - * DEBUGGING to 1.
|
| - */
|
| -#define DEBUGGING 0
|
| -
|
| -#include "native_client/src/shared/utils/debugging.h"
|
| -
|
| -/* Returns true if the given instructions are (runtime) equal. */
|
| -static Bool NaClInstSame(const NaClModeledInst* inst1,
|
| - const NaClModeledInst* inst2) {
|
| - if (inst1 == inst2) return TRUE;
|
| - if ((inst1 == NULL) || (inst2 == NULL)) return FALSE;
|
| - if (inst1->insttype != inst2->insttype) return FALSE;
|
| - if (inst1->flags != inst2->flags) return FALSE;
|
| - if (inst1->name != inst2->name) return FALSE;
|
| - if (inst1->opcode_ext != inst2->opcode_ext) return FALSE;
|
| - if (inst1->num_operands != inst2->num_operands) return FALSE;
|
| - if (inst1->operands != inst2->operands) return FALSE;
|
| - if (!NaClInstSame(inst1->next_rule, inst2->next_rule)) return FALSE;
|
| - return TRUE;
|
| -}
|
| -
|
| -/* Returns true if the given operands are equal. */
|
| -static Bool NaClOpSame(const NaClOp* op1, const NaClOp* op2) {
|
| - if ((op1->kind == op2->kind) && (op1->flags == op2->flags)) {
|
| - if (NULL == op1->format_string) {
|
| - return NULL == op2->format_string;
|
| - } else if (NULL != op2->format_string) {
|
| - return 0 == strcmp(op1->format_string, op2->format_string);
|
| - }
|
| - }
|
| - return FALSE;
|
| -}
|
| -
|
| -/* Compress the operands in the given instruction. */
|
| -static void NaClInstOpCompress(NaClInstTables* inst_tables,
|
| - NaClModeledInst* inst) {
|
| - size_t i;
|
| - Bool found = FALSE; /* until proven otherwise */
|
| - if (NULL == inst) return;
|
| - if (inst->num_operands <= inst_tables->ops_compressed_size) {
|
| - /* Note: Be sure to not overflow compressed array by stopping when
|
| - * there is no more room for the operands of the given instruction.
|
| - */
|
| - for (i = 0;
|
| - i <= inst_tables->ops_compressed_size - inst->num_operands;
|
| - ++i) {
|
| - size_t j;
|
| - Bool matches = TRUE; /* until proven otherwise */
|
| - for (j = 0; j < inst->num_operands; ++j) {
|
| - if (!NaClOpSame(inst->operands + j,
|
| - inst_tables->ops_compressed + i + j)) {
|
| - matches = FALSE;
|
| - break;
|
| - }
|
| - }
|
| - if (matches) {
|
| - /* Operands already in compressed table, use copy. */
|
| - inst->operands = inst_tables->ops_compressed + i;
|
| - found = TRUE;
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - if (!found) {
|
| - /* If reached, not in compressed table. Add. */
|
| - size_t new_size =
|
| - inst_tables->ops_compressed_size + inst->num_operands;
|
| - if (new_size > NACL_MAX_OPERANDS_TOTAL) {
|
| - NaClFatal("Not enough operand space to compress");
|
| - }
|
| - for (i = 0; i < inst->num_operands; ++i) {
|
| - size_t index = inst_tables->ops_compressed_size + i;
|
| - inst_tables->ops_compressed[index].kind = inst->operands[i].kind;
|
| - inst_tables->ops_compressed[index].flags = inst->operands[i].flags;
|
| - inst_tables->ops_compressed[index].format_string =
|
| - inst->operands[i].format_string;
|
| - }
|
| - inst->operands = inst_tables->ops_compressed +
|
| - inst_tables->ops_compressed_size;
|
| - inst_tables->ops_compressed_size = new_size;
|
| - }
|
| -}
|
| -
|
| -/* Records the number of instructions that compression was attempted on. */
|
| -static size_t num_uncompressed_instructions = 0;
|
| -
|
| -/* Compress the given instruction. */
|
| -static NaClModeledInst* NaClInstCompress(NaClInstTables* inst_tables,
|
| - NaClModeledInst* inst) {
|
| - size_t i;
|
| - if (inst == NULL) return NULL;
|
| - ++num_uncompressed_instructions;
|
| -
|
| - /* First compress additional rules associated with the given
|
| - * instruction, so that when we compare this instruction, the
|
| - * compression of the additional rules will automatically be counted.
|
| - */
|
| - inst->next_rule = NaClInstCompress(inst_tables, inst->next_rule);
|
| -
|
| - /* Compress the given instruction. */
|
| - NaClInstOpCompress(inst_tables, inst);
|
| -
|
| - /* Now see if we already have such an instruction. If so, use it. */
|
| - for (i = 0; i < inst_tables->inst_compressed_size; ++i) {
|
| - NaClModeledInst* comp_inst = inst_tables->inst_compressed[i];
|
| - if (NaClInstSame(inst, comp_inst)) return comp_inst;
|
| - }
|
| -
|
| - /* If reached, no such instruction exists, put it into the table. */
|
| - inst_tables->inst_compressed[i] = inst;
|
| - ++inst_tables->inst_compressed_size;
|
| - return inst;
|
| -}
|
| -
|
| -/* Compress operands of all instructions reachable from
|
| - * the given node.
|
| - */
|
| -static void NaClOpNodeCompress(NaClInstTables* inst_tables,
|
| - NaClModeledInstNode* node) {
|
| - if (NULL == node) return;
|
| - node->matching_inst = NaClInstCompress(inst_tables, node->matching_inst);
|
| - NaClOpNodeCompress(inst_tables, node->success);
|
| - NaClOpNodeCompress(inst_tables, node->fail);
|
| -}
|
| -
|
| -/* Finds the index to use for the given instruction, assuming
|
| - * it is a compressed instruction.
|
| - */
|
| -NaClOpcodeArrayOffset NaClFindInstIndex(NaClInstTables* inst_tables,
|
| - const NaClModeledInst* inst) {
|
| - size_t i;
|
| - if (NULL == inst) return NACL_OPCODE_NULL_OFFSET;
|
| - for (i = 0; i < inst_tables->inst_compressed_size; ++i) {
|
| - /* Fail if number of compressed instructions matches
|
| - * special NULL constant.
|
| - */
|
| - if (i == NACL_OPCODE_NULL_OFFSET) {
|
| - continue;
|
| - }
|
| - if (inst == inst_tables->inst_compressed[i]) {
|
| - return (NaClOpcodeArrayOffset) i;
|
| - }
|
| - }
|
| - NaClFatal("Unable to find instruction index\n");
|
| - /* NOT REACHED */
|
| - return NACL_OPCODE_NULL_OFFSET;
|
| -}
|
| -
|
| -/* The type for an array of opcode instruction lookups, for a
|
| - * given prefix.
|
| - */
|
| -typedef NaClOpcodeArrayOffset NaClInstOpcodeTable[NCDTABLESIZE];
|
| -
|
| -/* Adds the given table into the array of prefix opcode entries. */
|
| -static NaClPrefixOpcodeArrayOffset NaClOpcodeTableAdd(
|
| - NaClInstTables* inst_tables,
|
| - NaClInstOpcodeTable* table,
|
| - size_t table_size) {
|
| - size_t i;
|
| - size_t index;
|
| -
|
| - /* First see if we can overlay the table onto the existing
|
| - * lookup entries.
|
| - */
|
| - if (table_size <= inst_tables->opcode_lookup_size) {
|
| - size_t cutoff = inst_tables->opcode_lookup_size - table_size;
|
| - for (i = 0; i <= cutoff; ++i) {
|
| - size_t j;
|
| - Bool found = TRUE; /* until proven otherwise. */
|
| - for (j = 0; j < table_size; j++) {
|
| - if (inst_tables->opcode_lookup[i + j] != (*table)[j]) {
|
| - found = FALSE;
|
| - break;
|
| - }
|
| - }
|
| - if (found) {
|
| - return (NaClPrefixOpcodeArrayOffset) i;
|
| - }
|
| - }
|
| - }
|
| -
|
| - /* If reached, unable to overlay. Add to end of lookup entries. */
|
| - if (inst_tables->opcode_lookup_size + table_size >=
|
| - NACL_MAX_PREFIX_OPCODE_ENTRIES) {
|
| - NaClFatal("prefix opcode lookup table overflow");
|
| - }
|
| - index = inst_tables->opcode_lookup_size;
|
| - for (i = 0; i < table_size; ++i) {
|
| - inst_tables->opcode_lookup[index + i] = (*table)[i];
|
| - }
|
| - inst_tables->opcode_lookup_size += table_size;
|
| - return (NaClOpcodeArrayOffset) index;
|
| -}
|
| -
|
| -/* Compress prefix opcode lookups for the given prefix. */
|
| -static void NaClOpcodeTableCompressPrefix(
|
| - NaClInstTables* inst_tables,
|
| - NaClInstPrefix prefix) {
|
| - size_t i;
|
| - size_t table_size;
|
| - NaClInstOpcodeTable opcode_table;
|
| - uint8_t first_entry = 0;
|
| - uint8_t last_entry = NCDTABLESIZE - 1;
|
| -
|
| - /* Start by finding smallest region of opcodes for which
|
| - * the lookup values contain non-null entries.
|
| - */
|
| - for (i = 0; i < NCDTABLESIZE; ++i) {
|
| - if (NULL == inst_tables->inst_table[i][prefix]) {
|
| - first_entry = (uint8_t) i;
|
| - } else {
|
| - break;
|
| - }
|
| - }
|
| - for (i = last_entry; ; --i) {
|
| - if (NULL == inst_tables->inst_table[i][prefix]) {
|
| - last_entry = (uint8_t) i;
|
| - if (i == first_entry) break;
|
| - } else {
|
| - break;
|
| - }
|
| - if (i == 0) break; /* Added to deal with underflow. */
|
| - }
|
| -
|
| - /* Define only values for the region found. */
|
| - table_size = (last_entry - first_entry) + 1;
|
| -
|
| - /* Fill in remaining values. */
|
| - for (i = 0; i < table_size; ++i) {
|
| - opcode_table[i] = NaClFindInstIndex(
|
| - inst_tables,
|
| - inst_tables->inst_table[(int) first_entry + i][prefix]);
|
| - }
|
| -
|
| - /* Install the minimized table into the compressed data structures. */
|
| - inst_tables->opcode_lookup_first[prefix] = first_entry;
|
| - inst_tables->opcode_lookup_last[prefix] = last_entry;
|
| - inst_tables->opcode_lookup_entry[prefix] =
|
| - NaClOpcodeTableAdd(inst_tables, &opcode_table, table_size);
|
| -}
|
| -
|
| -/* Compress the prefix/opcode tables. Generates a single array of entries,
|
| - * and triples defining what portion of that array corresponds to
|
| - * the lookup table for a given prefix.
|
| - */
|
| -static void NaClOpcodeTableCompress(NaClInstTables* inst_tables) {
|
| - NaClInstPrefix prefix;
|
| - for (prefix = NoPrefix; prefix < NaClInstPrefixEnumSize; ++prefix) {
|
| - NaClOpcodeTableCompressPrefix(inst_tables, prefix);
|
| - }
|
| -}
|
| -
|
| -/* Walks over the modeled instructions and replaces duplicate
|
| - * operand entries.
|
| - */
|
| -void NaClOpCompress(NaClInstTables* inst_tables) {
|
| - int i;
|
| - NaClInstPrefix prefix;
|
| - fprintf(stderr, "Note: %"NACL_PRIuS" operands before compression, ",
|
| - inst_tables->operands_size);
|
| - /* Compress the undefined instruction. Note: Must appear first,
|
| - * so that we know the location of undefined for static initialization
|
| - * in ncdis_decode_tables.c
|
| - */
|
| - inst_tables->undefined_inst =
|
| - NaClInstCompress(inst_tables, inst_tables->undefined_inst);
|
| -
|
| - /* Compress all operands of instructions in the instruction opcode tables. */
|
| - for (prefix = NoPrefix; prefix < NaClInstPrefixEnumSize; ++prefix) {
|
| - for (i = 0; i < NCDTABLESIZE; ++i) {
|
| - inst_tables->inst_table[i][prefix]=
|
| - NaClInstCompress(inst_tables, inst_tables->inst_table[i][prefix]);
|
| - }
|
| - }
|
| -
|
| - /* Compress all operands of instructions in the instruction trie. */
|
| - NaClOpNodeCompress(inst_tables, inst_tables->inst_node_root);
|
| - fprintf(stderr, "%"NACL_PRIuS" after.\n",
|
| - inst_tables->ops_compressed_size);
|
| - fprintf(stderr, "Note: %"NACL_PRIuS" instruction before compression, "
|
| - "%"NACL_PRIuS" after.\n",
|
| - num_uncompressed_instructions,
|
| - inst_tables->inst_compressed_size);
|
| -
|
| - /* Compress the opcode table lookups. */
|
| - NaClOpcodeTableCompress(inst_tables);
|
| - fprintf(stderr, "Note: %d opcode table entries before compression, "
|
| - "%"NACL_PRIuS" after.\n",
|
| - NCDTABLESIZE * NaClInstPrefixEnumSize,
|
| - inst_tables->opcode_lookup_size);
|
| -}
|
|
|