Add command-line switches to generate_{jit,interpreter}.js

In order of precedence:
--all generates all tables
--table jit{,0f_16,0f_32} / interpreter{,0f_16,0f_32}

And optionally:
--output-dir /path/to/output (defaults to v86 build directory)

This is in prep to let the make system generate individual tables as required
using this script instead of the script generating all 3.

Have output of generate table files use .c suffix

Remove write_sync_if_changed

The function existed to stop make from recompiling v86*.wasm everytime from
having the tables regenerated. With the upcoming change, this becomes unnecessary.

Correct Makefile to show dependency structure for generate scripts
This commit is contained in:
Amaan Cheval 2018-02-16 16:02:18 +05:30 committed by Fabian
parent 9dc78d6c0d
commit 01e868a481
6 changed files with 118 additions and 61 deletions

View file

@ -4,8 +4,12 @@ BROWSER=chromium
NASM_TEST_DIR=./tests/nasm
COVERAGE_DIR=./tests/coverage
GEN_INSTRUCTION_TABLE_CMDS=./gen/generate_interpreter.js; ./gen/generate_jit.js;
GEN_SCRIPTS := $(wildcard gen/*.js)
JIT_TABLES=$(addprefix build/,jit.c jit0f_16.c jit0f_32.c)
INTERPRETER_TABLES=$(addprefix build/,interpreter.c interpreter0f_16.c interpreter0f_32.c)
INSTRUCTION_TABLES=$(JIT_TABLES) $(INTERPRETER_TABLES)
# Only the dependencies common to both generate_{jit,interpreter}.js
GEN_DEPENDENCIES=$(filter-out $(wildcard gen/generate*.js), $(wildcard gen/*.js))
# Enable manually and recompile v86-debug.wasm for coverage-enabled tests
ifeq ($(ENABLE_COV), 1)
@ -16,6 +20,15 @@ all: build/v86_all.js
browser: build/v86_all.js
wasm: build/v86.wasm
.PHONY: instruction_tables
instruction_tables: $(INSTRUCTION_TABLES)
$(JIT_TABLES): $(GEN_DEPENDENCIES) gen/generate_jit.js
./gen/generate_jit.js --output-dir $(dir $@) --table $(basename $(notdir $@))
$(INTERPRETER_TABLES): $(GEN_DEPENDENCIES) gen/generate_interpreter.js
./gen/generate_interpreter.js --output-dir $(dir $@) --table $(basename $(notdir $@))
# Used for nodejs builds and in order to profile code.
# `debug` gives identifiers a readable name, make sure it doesn't have any side effects.
CLOSURE_READABLE=--formatting PRETTY_PRINT --debug
@ -155,9 +168,8 @@ build/libv86-debug.js: $(CLOSURE) src/*.js lib/*.js src/browser/*.js
--js $(BROWSER_FILES)\
--js $(LIB_FILES)
build/v86.wasm: src/native/*.c src/native/*.h src/native/codegen/*.c src/native/codegen/*.h src/native/profiler/* src/native/call-indirect.ll $(GEN_SCRIPTS)
build/v86.wasm: src/native/*.c src/native/*.h src/native/codegen/*.c src/native/codegen/*.h src/native/profiler/* src/native/call-indirect.ll $(INSTRUCTION_TABLES)
mkdir -p build
$(GEN_INSTRUCTION_TABLE_CMDS)
-ls -lh build/v86.wasm
emcc src/native/*.c src/native/profiler/profiler.c src/native/codegen/codegen.c src/native/call-indirect.ll \
$(CC_FLAGS) \
@ -169,9 +181,8 @@ build/v86.wasm: src/native/*.c src/native/*.h src/native/codegen/*.c src/native/
-o build/v86.wasm
ls -lh build/v86.wasm
build/v86-debug.wasm: src/native/*.c src/native/*.h src/native/codegen/*.c src/native/codegen/*.h src/native/profiler/* src/native/*.ll $(GEN_SCRIPTS)
build/v86-debug.wasm: src/native/*.c src/native/*.h src/native/codegen/*.c src/native/codegen/*.h src/native/profiler/* src/native/*.ll $(INSTRUCTION_TABLES)
mkdir -p build/coverage
$(GEN_INSTRUCTION_TABLE_CMDS)
-ls -lh build/v86-debug.wasm
emcc src/native/*.c src/native/profiler/profiler.c src/native/codegen/codegen.c src/native/*.ll \
$(CC_FLAGS) \

View file

@ -5,13 +5,26 @@ const fs = require("fs");
const path = require("path");
const encodings = require("./x86_table");
const c_ast = require("./c_ast");
const { hex, write_sync_if_changed } = require("./util");
const { hex, get_switch_value, get_switch_exist } = require("./util");
const OUT_DIR = path.join(__dirname, "..", "build");
const OUT_DIR = get_switch_value("--output-dir") ||
path.join(__dirname, "..", "build");
const table_arg = get_switch_value("--table");
const gen_all = get_switch_exist("--all");
const to_generate = {
interpreter: gen_all || table_arg === "interpreter",
interpreter0f_16: gen_all || table_arg === "interpreter0f_16",
interpreter0f_32: gen_all || table_arg === "interpreter0f_32",
};
console.assert(
Object.keys(to_generate).some(k => to_generate[k]),
"Pass --table [table_name] or --all to pick which tables to generate"
);
gen_table();
function gen_read_imm_call(op, size_variant)
{
let size = (op.os || op.opcode % 2 === 1) ? size_variant : 8;
@ -393,10 +406,13 @@ function gen_table()
body: ["assert(false);"]
},
};
write_sync_if_changed(
path.join(OUT_DIR, "interpreter"),
c_ast.print_syntax_tree([table]).join("\n") + "\n"
);
if(to_generate.interpreter)
{
fs.writeFileSync(
path.join(OUT_DIR, "interpreter.c"),
c_ast.print_syntax_tree([table]).join("\n") + "\n"
);
}
const cases0f_16 = [];
const cases0f_32 = [];
@ -455,12 +471,20 @@ function gen_table()
body: ["assert(false);"]
},
};
write_sync_if_changed(
path.join(OUT_DIR, "interpreter0f_16"),
c_ast.print_syntax_tree([table0f_16]).join("\n") + "\n"
);
write_sync_if_changed(
path.join(OUT_DIR, "interpreter0f_32"),
c_ast.print_syntax_tree([table0f_32]).join("\n") + "\n"
);
if(to_generate.interpreter0f_16)
{
fs.writeFileSync(
path.join(OUT_DIR, "interpreter0f_16.c"),
c_ast.print_syntax_tree([table0f_16]).join("\n") + "\n"
);
}
if(to_generate.interpreter0f_32)
{
fs.writeFileSync(
path.join(OUT_DIR, "interpreter0f_32.c"),
c_ast.print_syntax_tree([table0f_32]).join("\n") + "\n"
);
}
}

View file

@ -5,14 +5,27 @@ const fs = require("fs");
const path = require("path");
const encodings = require("./x86_table");
const c_ast = require("./c_ast");
const { hex, write_sync_if_changed } = require("./util");
const { hex, get_switch_value, get_switch_exist } = require("./util");
const OUT_DIR = path.join(__dirname, "..", "build");
const OUT_DIR = get_switch_value("--output-dir") ||
path.join(__dirname, "..", "build");
const APPEND_NONFAULTING_FLAG = "instr_flags |= JIT_INSTR_NONFAULTING_FLAG;";
gen_table();
const table_arg = get_switch_value("--table");
const gen_all = get_switch_exist("--all");
const to_generate = {
jit: gen_all || table_arg === "jit",
jit0f_16: gen_all || table_arg === "jit0f_16",
jit0f_32: gen_all || table_arg === "jit0f_32",
};
console.assert(
Object.keys(to_generate).some(k => to_generate[k]),
"Pass --table [table_name] or --all to pick which tables to generate"
);
gen_table();
function gen_read_imm_call(op, size_variant)
{
@ -493,10 +506,14 @@ function gen_table()
body: ["assert(false);"]
},
};
write_sync_if_changed(
path.join(OUT_DIR, "jit"),
c_ast.print_syntax_tree([table]).join("\n") + "\n"
);
if(to_generate.jit)
{
fs.writeFileSync(
path.join(OUT_DIR, "jit.c"),
c_ast.print_syntax_tree([table]).join("\n") + "\n"
);
}
const cases0f_16 = [];
const cases0f_32 = [];
@ -555,12 +572,20 @@ function gen_table()
body: ["assert(false);"]
},
};
write_sync_if_changed(
path.join(OUT_DIR, "jit0f_16"),
c_ast.print_syntax_tree([table0f_16]).join("\n") + "\n"
);
write_sync_if_changed(
path.join(OUT_DIR, "jit0f_32"),
c_ast.print_syntax_tree([table0f_32]).join("\n") + "\n"
);
if(to_generate.jit0f_16)
{
fs.writeFileSync(
path.join(OUT_DIR, "jit0f_16.c"),
c_ast.print_syntax_tree([table0f_16]).join("\n") + "\n"
);
}
if(to_generate.jit0f_32)
{
fs.writeFileSync(
path.join(OUT_DIR, "jit0f_32.c"),
c_ast.print_syntax_tree([table0f_32]).join("\n") + "\n"
);
}
}

View file

@ -2,6 +2,7 @@
const assert = require("assert");
const fs = require("fs");
const process = require("process");
function hex(n, pad)
{
@ -11,29 +12,25 @@ function hex(n, pad)
return s;
}
function write_sync_if_changed(filename, contents)
function get_switch_value(arg_switch)
{
assert.ok(typeof contents === "string", "Contents must be a string for comparison");
const argv = process.argv;
const switch_i = argv.indexOf(arg_switch);
const val_i = switch_i + 1;
if(switch_i > -1 && val_i < argv.length)
{
return argv[switch_i + 1];
}
return false;
}
let existing_contents = null;
try
{
existing_contents = fs.readFileSync(filename).toString();
}
catch(e)
{
if(e.code !== "ENOENT") throw e;
}
const contents_changed = existing_contents !== contents;
if(contents_changed)
{
fs.writeFileSync(filename, contents);
console.log("[+] Writing", filename);
}
function get_switch_exist(arg_switch)
{
return process.argv.indexOf(arg_switch) > -1;
}
module.exports = {
hex,
write_sync_if_changed
get_switch_value,
get_switch_exist,
};

View file

@ -1467,13 +1467,13 @@ DEFINE_MODRM_INSTR1_READ32(instr32_FF_6, push32(___))
void run_instruction(int32_t opcode)
{
#include "../../build/interpreter"
#include "../../build/interpreter.c"
}
jit_instr_flags jit_instruction(int32_t opcode)
{
jit_instr_flags instr_flags = 0;
#include "../../build/jit"
#include "../../build/jit.c"
return instr_flags;
}

View file

@ -3657,25 +3657,25 @@ void instr_0FFF() {
void run_instruction0f_16(int32_t opcode)
{
#include "../../build/interpreter0f_16"
#include "../../build/interpreter0f_16.c"
}
void run_instruction0f_32(int32_t opcode)
{
#include "../../build/interpreter0f_32"
#include "../../build/interpreter0f_32.c"
}
jit_instr_flags jit_instruction0f_16(int32_t opcode)
{
jit_instr_flags instr_flags = 0;
#include "../../build/jit0f_16"
#include "../../build/jit0f_16.c"
return instr_flags;
}
jit_instr_flags jit_instruction0f_32(int32_t opcode)
{
jit_instr_flags instr_flags = 0;
#include "../../build/jit0f_32"
#include "../../build/jit0f_32.c"
return instr_flags;
}