Commit graph

370 commits

Author SHA1 Message Date
Fabian
e0aabb2937 Mark hintable nops as non-faulting 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
Fabian
02a7bbb8f7 Implement hintable nops 2020-08-30 19:29:53 -05:00
Fabian
f43ab3387a Remove use of cpu exceptions for trigger_gp for instructions 2020-08-30 19:29:53 -05:00
Fabian
5e82bc0e00 Remove use of cpu exceptions for trigger_ss (partially including switch_seg) 2020-08-30 19:29:53 -05:00
Fabian
4ee7da8f83 Remove use of cpu exceptions for divisions 2020-08-30 19:29:53 -05:00
Awal Garg
b3e415cf9f jit inline 0xC3 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
Awal Garg
4d622c165e jit inline nop instructions 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
dac9b4591b Simplify generate_interpreter.js 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
9b2b3250df Fix 8-bit jumps in 16-bit mode 2020-08-30 19:27:07 -05:00
Fabian
5995414f87 JIT: Follow call instructions 2020-08-30 19:27:07 -05:00
Fabian
ad7fa728b5 Annotate some instructions 2020-08-30 19:27:07 -05:00
Fabian
2609041e64 Don't fail when invalid instructions are analyzed/jitted 2020-08-30 19:27:07 -05:00
Fabian
8466ca205e Mark ud2 instruction as block boundary 2020-08-30 19:27:07 -05:00
Fabian
cba5491fc4 Multiple jit block entry points
- introduce multiple entry points per compiled wasm module, by passing
  the initial state to the generated function.
- continue analysing and compiling after instructions that change eip, but
  will eventually return to the next instruction, in particular CALLs
  (and generate an entry point for the following instruction)

This commit is incomplete in the sense that the container will crash
after some time of execution, as wasm table indices are never freed
2020-08-30 19:27:02 -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
2128f07796 jit: Inline 0x89 and 0x8b opcodes's reg variants 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
65bf2e350d Don't generate duplicate flags checks
Also simplify the generated analyzer code by just finding the jump
offset, not the computed jump target
2020-07-21 20:10:14 -05:00
Fabian
f8349af093 New block analysis, generation of state machine with multiple basic blocks
This commit consists of three components:

1. A new generated x86-parser that analyses instructions. For now, it
   only detects the control flow of an instruction: Whether it is a
   (conditional) jump, a normal instruction or a basic block boundary
2. A new function, jit_find_basic_blocks, that finds and connects basic
   blocks using 1. It loosely finds all basic blocks making up a function,
   i.e. it doesn't follow call or return instructions (but it does follow
   all near jumps). Different from our previous analysis, it also finds
   basic blocks in the strict sense that no basic block contains a jump
   into the middle of another basic block
3. A new code-generating function, jit_generate, that takes the output
   of 2 as input. It generates a state machine:
   - Each basic block becomes a case block in a switch-table
   - Each basic block ends with setting a state variable for the following basic block
   - The switch-table is inside a while(true) loop, which is terminated
     by return statements in basic blocks which are leaves

Additionally:
- Block linking has been removed as it is (mostly) obsoleted by these
  changes. It may later be reactived for call instructions
- The code generator API has been extended to generate the code for the state machine
- The iterations of the state machine are limited in order to avoid
  infinite loops that can't be interrupted
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
Fabian
0d5ca58354 Minor: Use freeze on instruction objects 2020-07-21 20:10:14 -05:00
Amaan Cheval
dffca42ca7 instructions: Call after_block_boundary from interpreter not instr
The instruction body shouldn't include anything but the instruction's
implementation.
2020-07-21 20:10:14 -05:00
Amaan Cheval
41c8241d5e x86_table: Mark state-altering instructions as JIT block boundaries
These instructions, if included within a compiled JIT block, may alter the
state_flags of a block entry (such as whether flat segmentation is used or not),
which may invalidate the block that is running - this caused bugs in OpenBSD
because of a block like this being compiled:

0xF81F2: 8E DB                mov ds, bx
0xF81F4: 8E D3                mov ss, bx
0xF81F6: 66 8B 26 B8 F5       mov esp, dword ptr [0xf5b8] <--
0xF81FB: 66 89 36 B8 F5       mov dword ptr [0xf5b8], esi <--

The memory accesses implicitly use DS. If we include flat-segmenetation as a
flag within state_flags and optimize calls to get_seg based on it, this behavior
would cause issues (and did, in OpenBSD).

By marking these instructions as block boundaries, we remediate that issue.
2020-07-21 20:10:14 -05:00
Amaan Cheval
4d87bebee9 gen: s/jump/block_boundary/ 2020-07-21 20:10:14 -05:00
Amaan Cheval
1f0e7c3ce0 fpu: Have opcode 0xDF use fixed_g instruction functions 2020-07-21 20:10:14 -05:00
Amaan Cheval
fca80793b8 fpu: Have opcode 0xDE use fixed_g instruction functions 2020-07-21 20:10:14 -05:00
Amaan Cheval
4910777084 fpu: Have opcode 0xDD use fixed_g instruction functions 2020-07-21 20:10:14 -05:00
Amaan Cheval
33c2b72553 fpu: Have opcode 0xDC use fixed_g instruction functions 2020-07-21 20:10:14 -05:00
Amaan Cheval
c3a856e944 fpu: Have opcode 0xDB use fixed_g instruction functions 2020-07-21 20:10:14 -05:00
Amaan Cheval
0f23cf2745 fpu: Have opcode 0xDA use fixed_g instruction functions 2020-07-21 20:10:14 -05:00
Amaan Cheval
df86637cb8 fpu: Have opcode 0xD9 use fixed_g 2020-07-21 20:10:14 -05:00
Amaan Cheval
173be47658 fpu: Have opcode 0xD8 use fixed_g and the regular instruction decoder 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
843527ac04 Apply stack_size_32 cache optimization to push r/m 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
3ffb2ac35f Apply stack_size_32 cache optimization to push imm 2020-07-21 20:10:14 -05:00
Amaan Cheval
3512d34314 Optimize push/pop JIT instructions to not check stack_size_32
We generate a version of the push/pop instruction with the stack_size_32 fixed,
since the state tends not to change much. If it does change, state_flags won't
match the output of pack_current_state_flags and the cache entry will therefore
be invalidated.
2020-07-21 20:10:14 -05:00