Commit graph

55 commits

Author SHA1 Message Date
Fabian 159aaaa01f Move imm reads into generate_jit 2020-12-31 19:14:31 -06:00
Fabian ab46fe4f37 Refactor modrm decoding for jit 2020-12-31 19:14:31 -06:00
Fabian 4e6d925ee3 Use gen_trigger_ud 2020-12-31 19:14:31 -06:00
Fabian 9853bdb868 Merge 16-bit and 32-bit 0f tables (saves 200kB on v86.wasm) 2020-12-31 19:14:31 -06:00
Fabian acb8ad5423 Avoid console.assert (doesn't throw) 2020-12-31 19:14:30 -06:00
Fabian c207400922 Fix Rust warnings 2020-12-31 19:14:29 -06:00
Fabian e99da40215 Make std/cld custom (FC/FD), remove unused unguarded_register and no_register properties from x86 table 2020-12-31 19:14:28 -06:00
Fabian a8308b988d Store registers in locals
This changes registers to be temporarily stored in wasm locals, across
each complete wasm module. Registers are moved from memory to locals
upon entering the wasm module and moved from locals to memory upon
leaving. Additionally, calls to functions that modify registers are
wrapped between moving registers to memory before and moving back to
locals after. This affects:

1. All non-custom instructions
2. safe_{read,write}_slow, since it may page fault (the slow path of all memory accesses)
3. task_switch_test* and trigger_ud
4. All block boundaries
5. The fallback functions of gen_safe_read_write (read-modify-write memory accesses)

The performance benefits are currently mostly eaten up by 1. and 4. (if
one calculates the total number of read/writes to registers in memory,
they are higher after this patch, as each instructions of typ 1. or 4.
requires moving all 8 register twice). This can be improved later by the
relatively mechanical work of making instructions custom (not
necessarily full code generation, only the part of the instruction where
registers are accessed). Multi-page wasm module generation will
significantly reduce the number of type 4. instructions.

Due to 2., the overall code size has significantly increased. This case
(the slow path of memory access) is often generated but rarely executed.
These moves can be removed in a later patch by a different scheme for
safe_{read,write}_slow, which has been left out of this patch for
simplicity of reviewing.

This also simplifies our code generation for storing registers, as

    instructions_body.const_i32(register_offset);
    // some computations ...
    instruction_body.store_i32();

turns into:

    // some computations ...
    write_register(register_index);

I.e., a prefix is not necessary anymore as locals are indexed directly.

Further patches will allow getting rid of some temporary locals, as
registers now can be used directly.
2020-08-30 19:37:15 -05:00
Fabian 440b67eda5 Support for gen_safe_write128 and code generation for MOVAPS/MOVDQA (0F29/660F7F) 2020-08-30 19:37:15 -05:00
Fabian ec059a9f27 Codegen for fpu instructions (D8 group) 2020-08-30 19:37:15 -05:00
Fabian 7e3f1ad401 gen_fn: Accept wasm builder, not jit context 2020-08-30 19:29:54 -05:00
Fabian 46f9bc9d00 Remove non-faulting property of instructions (all instructions are non-faulting) 2020-08-30 19:29:54 -05:00
Fabian 60d4a28e2c jit: Custom instructions can be block boundaries 2020-08-30 19:29:54 -05:00
Fabian a5cbf53da5 Fix jit in presence of new page fault handling
Makes the following a block boundary:

- push
- Any non-custom instruction that uses modrm encoding
- Any sse/fpu instruction

This commit affects performance negatively. In order to fix this, the
above instructions need to be implemented using custom code generators
for the memory access.
2020-08-30 19:29:53 -05:00
Fabian 70ae4b720a Remove use of raising cpu exceptions for trigger_ud 2020-08-30 19:29:53 -05:00
Fabian bdef74eced Generate code for task_switch_test{,_mmx}, use non-raising exceptions 2020-08-30 19:29:53 -05:00
Awal Garg c2c5e4f35c jit inline 0xC7
The generated rust code doesn't call read_imm* functions for custom
instructions now for the memory variant branches when both immediate
values and modrm byte is used
2020-08-30 19:29:53 -05:00
Fabian 1253b72906 Generate prefix handling for string instructions 2020-08-30 19:29:13 -05:00
Fabian 3a8d644d75 Port jit to Rust
The following files and functions were ported:
- jit.c
- codegen.c
- _jit functions in instructions*.c and misc_instr.c
- generate_{analyzer,jit}.js (produces Rust code)
- jit_* from cpu.c

And the following data structures:
- hot_code_addresses
- wasm_table_index_free_list
- entry_points
- jit_cache_array
- page_first_jit_cache_entry

Other miscellaneous changes:
- Page is an abstract type
- Addresses, locals and bitflags are unsigned
- Make the number of entry points a growable type
- Avoid use of global state wherever possible
- Delete string packing
- Make CachedStateFlags abstract
- Make AnalysisType product type
- Make BasicBlockType product type
- Restore opcode assertion
- Set opt-level=2 in debug mode (for test performance)
- Delete JIT_ALWAYS instrumentation (now possible via api)
- Refactor generate_analyzer.js
- Refactor generate_jit.js
2020-08-30 19:29:13 -05:00
Fabian 2609041e64 Don't fail when invalid instructions are analyzed/jitted 2020-08-30 19:27:07 -05:00
Amaan Cheval d1b728b582 generate_jit (minor): Use standard gen_codegen_call for trigger_ud 2020-07-21 20:10:14 -05:00
Amaan Cheval cde8a2d005 codegen: s/gen_fn[0-9]/gen_fn[0-9]_const/ to indicate inline args
We need to differentiate between gen_fn, gen_call_fn, etc. This is a
step in the right direction, but isn't quite enough.
2020-07-21 20:10:14 -05:00
Amaan Cheval 7fec029937 generate_jit: Support encoding.custom for encoding.e generic instrs 2020-07-21 20:10:14 -05:00
Amaan Cheval fdd4dbe5ee generate_jit: Comment regarding LEA special case 2020-07-21 20:10:14 -05:00
Fabian 39d8d17031 Make 8f custom, simplify generate_jit by removing handling of requires_prefix_call 2020-07-21 20:10:14 -05:00
Fabian ded423b1c5 x86 table: Add remaining 0f instructions, simplify gen scripts 2020-07-21 20:10:14 -05:00
Fabian a9b5f153a8 Move around and add some assertions 2020-07-21 20:10:14 -05:00
Fabian eb7b33df7b Fix trigger #ud instead of generating call to it 2020-07-21 20:10:14 -05:00
Amaan Cheval 4d87bebee9 gen: s/jump/block_boundary/ 2020-07-21 20:10:14 -05:00
Awal Garg 54a43ab437 improve segment prefix handling and custom code generation for lea 2020-07-21 20:10:14 -05:00
Fabian 43288ecdbd Simplify modrm code generation
Previously a callback was used to insert the read_imm call after
modrm_resolve. The new api uses two calls, allowing the removal of some
edge cases and deletion of extraneous functions
2020-07-21 20:10:14 -05:00
Amaan Cheval 21909fd5fd Generate _jit_[reg,mem] calls for custom modrm instructions
This allows for a cleaner separation for custom modrm instructions
2020-07-21 20:10:14 -05:00
Amaan Cheval a09ace9c95 Revert "generate_jit: Refactor to deduplicate custom call generation"
This reverts commit fcbaea9cc989961adffa64b30afcde9579dcaab0.
2020-07-21 20:10:14 -05:00
Amaan Cheval b36a03ca40 generate_jit: Refactor to deduplicate custom call generation 2020-07-21 20:10:14 -05:00
Amaan Cheval 515a8f4111 generate_jit: Allow custom annotation for fixed_g instructions
In prep for 0xFF - push r/m to be optimized
2020-07-21 20:10:14 -05:00
Amaan Cheval ccb666ce6b Have generate_{jit,interpreter}.js scripts "mkdir -p" for --output-dir 2020-07-21 20:10:14 -05:00
Amaan Cheval ce1ca76aea Backup and generate diff in generate_{jit,interpreter}, not Makefile 2020-07-21 20:10:14 -05:00
Amaan Cheval 3b4ae644a2 Have generate files print possible options for CLI switch arg 2020-07-21 20:10:14 -05:00
Amaan Cheval 01e868a481 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
2020-07-21 20:10:14 -05:00
Amaan Cheval 948fa047d0 Generate instruction tables into build directory, and only when changed 2020-07-21 20:10:14 -05:00
Amaan Cheval 15d75b0f9d Minor: remove extra newlines 2020-07-21 20:10:14 -05:00
Amaan Cheval 660d9c83c0 Trailing comma 2020-07-21 20:10:14 -05:00
Amaan Cheval 17f98b1148 Refactor jit table generator to have caller perform optimization
Pass postfixes to gen_modrm_mem_reg_split so that the function doesn't need to
bother with conditions under which to apply the optimization.
2020-07-21 20:10:14 -05:00
Amaan Cheval 6edb13d053 Assert that jump instructions can't also be nonfaulting 2020-07-21 20:10:14 -05:00
Amaan Cheval 3ea84e6ca2 s/flags/instr_flags/ and prevent extra newlines for ignore_mod instructions 2020-07-21 20:10:14 -05:00
Amaan Cheval a265568443 Minor: jshint 2020-07-21 20:10:14 -05:00
Amaan Cheval d5212a1914 Update generate_jit and enable JIT's nonfaulting eip optimization 2020-07-21 20:10:14 -05:00
Amaan Cheval bc03a26e4c Minor typo 2020-07-21 20:10:14 -05:00
Amaan Cheval c681bef307 Have jit_instruction actually return a flag status
This gets rid of the old global variable that let us return status flags from
jit_instruction. As a caveat, though, all prefix instructions also need to
return the status / tack it onto the existing status. This could give rise to
subtle bugs if instructions that mean to update the status don't propogate the
return status all the way up the chain.
2020-07-21 20:10:14 -05:00
Amaan Cheval 99098cc4df Remove _scratch from codegen function names.
This reverts parts of commit d779df89714ef784a1f0ebb264ed5b9fe8727fb1.
2020-07-21 20:10:13 -05:00