mirror of
https://github.com/copy/v86.git
synced 2025-12-31 04:23:15 +00:00
switch to rust 2021, fix imports
This commit is contained in:
parent
d04046d958
commit
2996c087fd
28 changed files with 358 additions and 326 deletions
|
|
@ -2,6 +2,7 @@
|
|||
name = "v86"
|
||||
version = "0.1.0"
|
||||
publish = false
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
|
|
|||
|
|
@ -133,15 +133,15 @@ function gen_instruction_body(encodings, size)
|
|||
|
||||
if(has_66.length) {
|
||||
const body = gen_instruction_body_after_prefix(has_66, size);
|
||||
if_blocks.push({ condition: "cpu.prefixes & ::prefix::PREFIX_66 != 0", body, });
|
||||
if_blocks.push({ condition: "cpu.prefixes & prefix::PREFIX_66 != 0", body, });
|
||||
}
|
||||
if(has_F2.length) {
|
||||
const body = gen_instruction_body_after_prefix(has_F2, size);
|
||||
if_blocks.push({ condition: "cpu.prefixes & ::prefix::PREFIX_F2 != 0", body, });
|
||||
if_blocks.push({ condition: "cpu.prefixes & prefix::PREFIX_F2 != 0", body, });
|
||||
}
|
||||
if(has_F3.length) {
|
||||
const body = gen_instruction_body_after_prefix(has_F3, size);
|
||||
if_blocks.push({ condition: "cpu.prefixes & ::prefix::PREFIX_F3 != 0", body, });
|
||||
if_blocks.push({ condition: "cpu.prefixes & prefix::PREFIX_F3 != 0", body, });
|
||||
}
|
||||
|
||||
const else_block = {
|
||||
|
|
@ -199,7 +199,7 @@ function gen_instruction_body_after_prefix(encodings, size)
|
|||
|
||||
default_case: {
|
||||
body: [
|
||||
"analysis.ty = ::analysis::AnalysisType::BlockBoundary;",
|
||||
"analysis.ty = analysis::AnalysisType::BlockBoundary;",
|
||||
"analysis.no_next_instruction = true;",
|
||||
],
|
||||
}
|
||||
|
|
@ -218,14 +218,14 @@ function gen_instruction_body_after_fixed_g(encoding, size)
|
|||
const instruction_postfix = [];
|
||||
|
||||
if(encoding.custom_sti) {
|
||||
instruction_postfix.push("analysis.ty = ::analysis::AnalysisType::STI;");
|
||||
instruction_postfix.push("analysis.ty = analysis::AnalysisType::STI;");
|
||||
}
|
||||
else if(
|
||||
encoding.block_boundary &&
|
||||
// jump_offset_imm: Is a block boundary, but gets a different type (Jump) below
|
||||
!encoding.jump_offset_imm || (!encoding.custom && encoding.e))
|
||||
{
|
||||
instruction_postfix.push("analysis.ty = ::analysis::AnalysisType::BlockBoundary;");
|
||||
instruction_postfix.push("analysis.ty = analysis::AnalysisType::BlockBoundary;");
|
||||
}
|
||||
|
||||
if(encoding.no_next_instruction)
|
||||
|
|
@ -239,7 +239,7 @@ function gen_instruction_body_after_fixed_g(encoding, size)
|
|||
|
||||
if(encoding.prefix)
|
||||
{
|
||||
const instruction_name = "::analysis::" + make_instruction_name(encoding, size) + "_analyze";
|
||||
const instruction_name = "analysis::" + make_instruction_name(encoding, size) + "_analyze";
|
||||
const args = ["cpu", "analysis"];
|
||||
|
||||
assert(!imm_read);
|
||||
|
|
@ -259,14 +259,14 @@ function gen_instruction_body_after_fixed_g(encoding, size)
|
|||
if(encoding.mem_ud)
|
||||
{
|
||||
mem_postfix.push(
|
||||
"analysis.ty = ::analysis::AnalysisType::BlockBoundary;"
|
||||
"analysis.ty = analysis::AnalysisType::BlockBoundary;"
|
||||
);
|
||||
}
|
||||
|
||||
if(encoding.reg_ud)
|
||||
{
|
||||
reg_postfix.push(
|
||||
"analysis.ty = ::analysis::AnalysisType::BlockBoundary;"
|
||||
"analysis.ty = analysis::AnalysisType::BlockBoundary;"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -287,7 +287,7 @@ function gen_instruction_body_after_fixed_g(encoding, size)
|
|||
if_blocks: [{
|
||||
condition: "modrm_byte < 0xC0",
|
||||
body: [].concat(
|
||||
gen_call("::analysis::modrm_analyze", ["cpu", "modrm_byte"]),
|
||||
gen_call("analysis::modrm_analyze", ["cpu", "modrm_byte"]),
|
||||
mem_postfix,
|
||||
),
|
||||
}],
|
||||
|
|
@ -320,11 +320,11 @@ function gen_instruction_body_after_fixed_g(encoding, size)
|
|||
(encoding.opcode & ~0x3) === 0xE0
|
||||
);
|
||||
const condition_index = encoding.opcode & 0xFF;
|
||||
body.push(`analysis.ty = ::analysis::AnalysisType::Jump { offset: jump_offset as i32, condition: Some(0x${hex(condition_index, 2)}), is_32: cpu.osize_32() };`);
|
||||
body.push(`analysis.ty = analysis::AnalysisType::Jump { offset: jump_offset as i32, condition: Some(0x${hex(condition_index, 2)}), is_32: cpu.osize_32() };`);
|
||||
}
|
||||
else
|
||||
{
|
||||
body.push(`analysis.ty = ::analysis::AnalysisType::Jump { offset: jump_offset as i32, condition: None, is_32: cpu.osize_32() };`);
|
||||
body.push(`analysis.ty = analysis::AnalysisType::Jump { offset: jump_offset as i32, condition: None, is_32: cpu.osize_32() };`);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -415,7 +415,10 @@ function gen_table()
|
|||
{
|
||||
const code = [
|
||||
"#[cfg_attr(rustfmt, rustfmt_skip)]",
|
||||
"pub fn analyzer(opcode: u32, cpu: &mut ::cpu_context::CpuContext, analysis: &mut ::analysis::Analysis) {",
|
||||
"use crate::analysis;",
|
||||
"use crate::prefix;",
|
||||
"use crate::cpu_context;",
|
||||
"pub fn analyzer(opcode: u32, cpu: &mut cpu_context::CpuContext, analysis: &mut analysis::Analysis) {",
|
||||
table,
|
||||
"}",
|
||||
];
|
||||
|
|
@ -472,7 +475,10 @@ function gen_table()
|
|||
const code = [
|
||||
"#![allow(unused)]",
|
||||
"#[cfg_attr(rustfmt, rustfmt_skip)]",
|
||||
"pub fn analyzer(opcode: u32, cpu: &mut ::cpu_context::CpuContext, analysis: &mut ::analysis::Analysis) {",
|
||||
"use crate::analysis;",
|
||||
"use crate::prefix;",
|
||||
"use crate::cpu_context;",
|
||||
"pub fn analyzer(opcode: u32, cpu: &mut cpu_context::CpuContext, analysis: &mut analysis::Analysis) {",
|
||||
table0f,
|
||||
"}"
|
||||
];
|
||||
|
|
|
|||
|
|
@ -139,18 +139,18 @@ function gen_instruction_body(encodings, size)
|
|||
|
||||
if(has_66.length) {
|
||||
const body = gen_instruction_body_after_prefix(has_66, size);
|
||||
if_blocks.push({ condition: "prefixes_ & ::prefix::PREFIX_66 != 0", body, });
|
||||
if_blocks.push({ condition: "prefixes_ & prefix::PREFIX_66 != 0", body, });
|
||||
}
|
||||
if(has_F2.length) {
|
||||
const body = gen_instruction_body_after_prefix(has_F2, size);
|
||||
if_blocks.push({ condition: "prefixes_ & ::prefix::PREFIX_F2 != 0", body, });
|
||||
if_blocks.push({ condition: "prefixes_ & prefix::PREFIX_F2 != 0", body, });
|
||||
}
|
||||
if(has_F3.length) {
|
||||
const body = gen_instruction_body_after_prefix(has_F3, size);
|
||||
if_blocks.push({ condition: "prefixes_ & ::prefix::PREFIX_F3 != 0", body, });
|
||||
if_blocks.push({ condition: "prefixes_ & prefix::PREFIX_F3 != 0", body, });
|
||||
}
|
||||
|
||||
const check_prefixes = encoding.sse ? "(::prefix::PREFIX_66 | ::prefix::PREFIX_F2 | ::prefix::PREFIX_F3)" : "(::prefix::PREFIX_F2 | ::prefix::PREFIX_F3)";
|
||||
const check_prefixes = encoding.sse ? "(prefix::PREFIX_66 | prefix::PREFIX_F2 | prefix::PREFIX_F3)" : "(prefix::PREFIX_F2 | prefix::PREFIX_F3)";
|
||||
|
||||
const else_block = {
|
||||
body: [].concat(
|
||||
|
|
@ -408,11 +408,12 @@ function gen_table()
|
|||
const code = [
|
||||
"#![cfg_attr(rustfmt, rustfmt_skip)]",
|
||||
|
||||
"use cpu::cpu::{after_block_boundary, modrm_resolve};",
|
||||
"use cpu::cpu::{read_imm8, read_imm8s, read_imm16, read_imm32s, read_moffs};",
|
||||
"use cpu::cpu::{task_switch_test, trigger_ud, DEBUG};",
|
||||
"use cpu::instructions;",
|
||||
"use cpu::global_pointers::{instruction_pointer, prefixes};",
|
||||
"use crate::cpu::cpu::{after_block_boundary, modrm_resolve};",
|
||||
"use crate::cpu::cpu::{read_imm8, read_imm8s, read_imm16, read_imm32s, read_moffs};",
|
||||
"use crate::cpu::cpu::{task_switch_test, trigger_ud, DEBUG};",
|
||||
"use crate::cpu::instructions;",
|
||||
"use crate::cpu::global_pointers::{instruction_pointer, prefixes};",
|
||||
"use crate::prefix;",
|
||||
|
||||
"pub unsafe fn run(opcode: u32) {",
|
||||
table,
|
||||
|
|
@ -471,12 +472,13 @@ function gen_table()
|
|||
const code = [
|
||||
"#![cfg_attr(rustfmt, rustfmt_skip)]",
|
||||
|
||||
"use cpu::cpu::{after_block_boundary, modrm_resolve};",
|
||||
"use cpu::cpu::{read_imm8, read_imm16, read_imm32s};",
|
||||
"use cpu::cpu::{task_switch_test, task_switch_test_mmx, trigger_ud};",
|
||||
"use cpu::cpu::DEBUG;",
|
||||
"use cpu::instructions_0f;",
|
||||
"use cpu::global_pointers::{instruction_pointer, prefixes};",
|
||||
"use crate::cpu::cpu::{after_block_boundary, modrm_resolve};",
|
||||
"use crate::cpu::cpu::{read_imm8, read_imm16, read_imm32s};",
|
||||
"use crate::cpu::cpu::{task_switch_test, task_switch_test_mmx, trigger_ud};",
|
||||
"use crate::cpu::cpu::DEBUG;",
|
||||
"use crate::cpu::instructions_0f;",
|
||||
"use crate::cpu::global_pointers::{instruction_pointer, prefixes};",
|
||||
"use crate::prefix;",
|
||||
|
||||
"pub unsafe fn run(opcode: u32) {",
|
||||
table0f,
|
||||
|
|
|
|||
|
|
@ -133,15 +133,15 @@ function gen_instruction_body(encodings, size)
|
|||
|
||||
if(has_66.length) {
|
||||
const body = gen_instruction_body_after_prefix(has_66, size);
|
||||
if_blocks.push({ condition: "ctx.cpu.prefixes & ::prefix::PREFIX_66 != 0", body, });
|
||||
if_blocks.push({ condition: "ctx.cpu.prefixes & prefix::PREFIX_66 != 0", body, });
|
||||
}
|
||||
if(has_F2.length) {
|
||||
const body = gen_instruction_body_after_prefix(has_F2, size);
|
||||
if_blocks.push({ condition: "ctx.cpu.prefixes & ::prefix::PREFIX_F2 != 0", body, });
|
||||
if_blocks.push({ condition: "ctx.cpu.prefixes & prefix::PREFIX_F2 != 0", body, });
|
||||
}
|
||||
if(has_F3.length) {
|
||||
const body = gen_instruction_body_after_prefix(has_F3, size);
|
||||
if_blocks.push({ condition: "ctx.cpu.prefixes & ::prefix::PREFIX_F3 != 0", body, });
|
||||
if_blocks.push({ condition: "ctx.cpu.prefixes & prefix::PREFIX_F3 != 0", body, });
|
||||
}
|
||||
|
||||
const else_block = {
|
||||
|
|
@ -199,8 +199,8 @@ function gen_instruction_body_after_prefix(encodings, size)
|
|||
|
||||
default_case: {
|
||||
body: [].concat(
|
||||
gen_call(`::codegen::gen_trigger_ud`, ["ctx"]),
|
||||
"*instr_flags |= ::jit::JIT_INSTR_BLOCK_BOUNDARY_FLAG;"
|
||||
gen_call(`codegen::gen_trigger_ud`, ["ctx"]),
|
||||
"*instr_flags |= jit::JIT_INSTR_BLOCK_BOUNDARY_FLAG;"
|
||||
),
|
||||
}
|
||||
},
|
||||
|
|
@ -218,7 +218,7 @@ function gen_instruction_body_after_fixed_g(encoding, size)
|
|||
|
||||
if(encoding.block_boundary || (!encoding.custom && encoding.e))
|
||||
{
|
||||
instruction_postfix.push("*instr_flags |= ::jit::JIT_INSTR_BLOCK_BOUNDARY_FLAG;");
|
||||
instruction_postfix.push("*instr_flags |= jit::JIT_INSTR_BLOCK_BOUNDARY_FLAG;");
|
||||
}
|
||||
|
||||
const instruction_prefix = [];
|
||||
|
|
@ -226,7 +226,7 @@ function gen_instruction_body_after_fixed_g(encoding, size)
|
|||
if(encoding.task_switch_test || encoding.sse)
|
||||
{
|
||||
instruction_prefix.push(
|
||||
gen_call(encoding.sse ? "::codegen::gen_task_switch_test_mmx" : "::codegen::gen_task_switch_test", ["ctx"])
|
||||
gen_call(encoding.sse ? "codegen::gen_task_switch_test_mmx" : "codegen::gen_task_switch_test", ["ctx"])
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -247,10 +247,10 @@ function gen_instruction_body_after_fixed_g(encoding, size)
|
|||
else
|
||||
{
|
||||
instruction_prefix.push(
|
||||
gen_call("::codegen::gen_move_registers_from_locals_to_memory", ["ctx"])
|
||||
gen_call("codegen::gen_move_registers_from_locals_to_memory", ["ctx"])
|
||||
);
|
||||
instruction_postfix.push(
|
||||
gen_call("::codegen::gen_move_registers_from_memory_to_locals", ["ctx"])
|
||||
gen_call("codegen::gen_move_registers_from_memory_to_locals", ["ctx"])
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -263,14 +263,14 @@ function gen_instruction_body_after_fixed_g(encoding, size)
|
|||
if(encoding.mem_ud)
|
||||
{
|
||||
mem_postfix.push(
|
||||
"*instr_flags |= ::jit::JIT_INSTR_BLOCK_BOUNDARY_FLAG;"
|
||||
"*instr_flags |= jit::JIT_INSTR_BLOCK_BOUNDARY_FLAG;"
|
||||
);
|
||||
}
|
||||
|
||||
if(encoding.reg_ud)
|
||||
{
|
||||
reg_postfix.push(
|
||||
"*instr_flags |= ::jit::JIT_INSTR_BLOCK_BOUNDARY_FLAG;"
|
||||
"*instr_flags |= jit::JIT_INSTR_BLOCK_BOUNDARY_FLAG;"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -284,7 +284,7 @@ function gen_instruction_body_after_fixed_g(encoding, size)
|
|||
|
||||
return [].concat(
|
||||
instruction_prefix,
|
||||
gen_call(`::codegen::gen_fn${args.length - 2}_const`, args),
|
||||
gen_call(`codegen::gen_fn${args.length - 2}_const`, args),
|
||||
reg_postfix,
|
||||
instruction_postfix
|
||||
);
|
||||
|
|
@ -313,16 +313,16 @@ function gen_instruction_body_after_fixed_g(encoding, size)
|
|||
if_blocks: [{
|
||||
condition: "modrm_byte < 0xC0",
|
||||
body: [].concat(
|
||||
"let addr = ::modrm::decode(ctx.cpu, modrm_byte);",
|
||||
"let addr = modrm::decode(ctx.cpu, modrm_byte);",
|
||||
imm_read_bindings,
|
||||
gen_call(`::jit_instructions::${instruction_name}_mem_jit`, mem_args),
|
||||
gen_call(`jit_instructions::${instruction_name}_mem_jit`, mem_args),
|
||||
mem_postfix
|
||||
),
|
||||
}],
|
||||
else_block: {
|
||||
body: [].concat(
|
||||
imm_read_bindings,
|
||||
gen_call(`::jit_instructions::${instruction_name}_reg_jit`, reg_args),
|
||||
gen_call(`jit_instructions::${instruction_name}_reg_jit`, reg_args),
|
||||
reg_postfix
|
||||
),
|
||||
},
|
||||
|
|
@ -354,17 +354,17 @@ function gen_instruction_body_after_fixed_g(encoding, size)
|
|||
if_blocks: [{
|
||||
condition: "modrm_byte < 0xC0",
|
||||
body: [].concat(
|
||||
"let addr = ::modrm::decode(ctx.cpu, modrm_byte);",
|
||||
gen_call(`::codegen::gen_modrm_resolve`, ["ctx", "addr"]),
|
||||
"let addr = modrm::decode(ctx.cpu, modrm_byte);",
|
||||
gen_call(`codegen::gen_modrm_resolve`, ["ctx", "addr"]),
|
||||
imm_read_bindings,
|
||||
gen_call(`::codegen::gen_modrm_fn${mem_args.length - 2}`, mem_args),
|
||||
gen_call(`codegen::gen_modrm_fn${mem_args.length - 2}`, mem_args),
|
||||
mem_postfix
|
||||
),
|
||||
}],
|
||||
else_block: {
|
||||
body: [].concat(
|
||||
imm_read_bindings,
|
||||
gen_call(`::codegen::gen_fn${reg_args.length - 2}_const`, reg_args),
|
||||
gen_call(`codegen::gen_fn${reg_args.length - 2}_const`, reg_args),
|
||||
reg_postfix
|
||||
),
|
||||
},
|
||||
|
|
@ -392,7 +392,7 @@ function gen_instruction_body_after_fixed_g(encoding, size)
|
|||
return [].concat(
|
||||
instruction_prefix,
|
||||
imm_read_bindings,
|
||||
gen_call(`::jit_instructions::${instruction_name}_jit`, args),
|
||||
gen_call(`jit_instructions::${instruction_name}_jit`, args),
|
||||
instruction_postfix
|
||||
);
|
||||
}
|
||||
|
|
@ -423,7 +423,7 @@ function gen_instruction_body_after_fixed_g(encoding, size)
|
|||
return [].concat(
|
||||
instruction_prefix,
|
||||
imm_read_bindings,
|
||||
gen_call(`::codegen::gen_fn${args.length - 2}_const`, args),
|
||||
gen_call(`codegen::gen_fn${args.length - 2}_const`, args),
|
||||
instruction_postfix
|
||||
);
|
||||
}
|
||||
|
|
@ -493,7 +493,14 @@ function gen_table()
|
|||
{
|
||||
const code = [
|
||||
"#[cfg_attr(rustfmt, rustfmt_skip)]",
|
||||
"pub fn jit(opcode: u32, ctx: &mut ::jit::JitContext, instr_flags: &mut u32) {",
|
||||
|
||||
"use crate::prefix;",
|
||||
"use crate::jit;",
|
||||
"use crate::jit_instructions;",
|
||||
"use crate::modrm;",
|
||||
"use crate::codegen;",
|
||||
|
||||
"pub fn jit(opcode: u32, ctx: &mut jit::JitContext, instr_flags: &mut u32) {",
|
||||
table,
|
||||
"}",
|
||||
];
|
||||
|
|
@ -549,7 +556,14 @@ function gen_table()
|
|||
{
|
||||
const code = [
|
||||
"#[cfg_attr(rustfmt, rustfmt_skip)]",
|
||||
"pub fn jit(opcode: u32, ctx: &mut ::jit::JitContext, instr_flags: &mut u32) {",
|
||||
|
||||
"use crate::prefix;",
|
||||
"use crate::jit;",
|
||||
"use crate::jit_instructions;",
|
||||
"use crate::modrm;",
|
||||
"use crate::codegen;",
|
||||
|
||||
"pub fn jit(opcode: u32, ctx: &mut jit::JitContext, instr_flags: &mut u32) {",
|
||||
table0f,
|
||||
"}",
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
#![allow(non_snake_case)]
|
||||
|
||||
use cpu_context::CpuContext;
|
||||
use prefix::{PREFIX_66, PREFIX_67, PREFIX_F2, PREFIX_F3};
|
||||
use regs::{CS, DS, ES, FS, GS, SS};
|
||||
use crate::cpu_context::CpuContext;
|
||||
use crate::gen;
|
||||
use crate::modrm;
|
||||
use crate::prefix::{PREFIX_66, PREFIX_67, PREFIX_F2, PREFIX_F3};
|
||||
use crate::regs::{CS, DS, ES, FS, GS, SS};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub enum AnalysisType {
|
||||
|
|
@ -30,12 +32,12 @@ pub fn analyze_step(mut cpu: &mut CpuContext) -> Analysis {
|
|||
};
|
||||
cpu.prefixes = 0;
|
||||
let opcode = cpu.read_imm8() as u32 | (cpu.osize_32() as u32) << 8;
|
||||
::gen::analyzer::analyzer(opcode, &mut cpu, &mut analysis);
|
||||
gen::analyzer::analyzer(opcode, &mut cpu, &mut analysis);
|
||||
analysis
|
||||
}
|
||||
|
||||
pub fn analyze_step_handle_prefix(cpu: &mut CpuContext, analysis: &mut Analysis) {
|
||||
::gen::analyzer::analyzer(
|
||||
gen::analyzer::analyzer(
|
||||
cpu.read_imm8() as u32 | (cpu.osize_32() as u32) << 8,
|
||||
cpu,
|
||||
analysis,
|
||||
|
|
@ -52,10 +54,10 @@ pub fn analyze_step_handle_segment_prefix(
|
|||
}
|
||||
|
||||
pub fn instr16_0F_analyze(cpu: &mut CpuContext, analysis: &mut Analysis) {
|
||||
::gen::analyzer0f::analyzer(cpu.read_imm8() as u32, cpu, analysis)
|
||||
gen::analyzer0f::analyzer(cpu.read_imm8() as u32, cpu, analysis)
|
||||
}
|
||||
pub fn instr32_0F_analyze(cpu: &mut CpuContext, analysis: &mut Analysis) {
|
||||
::gen::analyzer0f::analyzer(cpu.read_imm8() as u32 | 0x100, cpu, analysis)
|
||||
gen::analyzer0f::analyzer(cpu.read_imm8() as u32 | 0x100, cpu, analysis)
|
||||
}
|
||||
pub fn instr_26_analyze(cpu: &mut CpuContext, analysis: &mut Analysis) {
|
||||
analyze_step_handle_segment_prefix(ES, cpu, analysis)
|
||||
|
|
@ -96,4 +98,4 @@ pub fn instr_F3_analyze(cpu: &mut CpuContext, analysis: &mut Analysis) {
|
|||
analyze_step_handle_prefix(cpu, analysis)
|
||||
}
|
||||
|
||||
pub fn modrm_analyze(ctx: &mut CpuContext, modrm_byte: u8) { ::modrm::skip(ctx, modrm_byte); }
|
||||
pub fn modrm_analyze(ctx: &mut CpuContext, modrm_byte: u8) { modrm::skip(ctx, modrm_byte); }
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
use cpu::cpu::{
|
||||
use crate::cpu::cpu::{
|
||||
tlb_data, FLAG_CARRY, FLAG_OVERFLOW, FLAG_SIGN, FLAG_ZERO, OPSIZE_16, OPSIZE_32, OPSIZE_8,
|
||||
TLB_GLOBAL, TLB_HAS_CODE, TLB_NO_USER, TLB_READONLY, TLB_VALID,
|
||||
};
|
||||
use cpu::global_pointers;
|
||||
use cpu::memory;
|
||||
use jit::{Instruction, InstructionOperand, InstructionOperandDest, JitContext};
|
||||
use modrm;
|
||||
use modrm::ModrmByte;
|
||||
use profiler;
|
||||
use regs;
|
||||
use wasmgen::wasm_builder::{WasmBuilder, WasmLocal, WasmLocalI64};
|
||||
use crate::cpu::global_pointers;
|
||||
use crate::cpu::memory;
|
||||
use crate::jit::{Instruction, InstructionOperand, InstructionOperandDest, JitContext};
|
||||
use crate::modrm;
|
||||
use crate::modrm::ModrmByte;
|
||||
use crate::opstats;
|
||||
use crate::profiler;
|
||||
use crate::regs;
|
||||
use crate::wasmgen::wasm_builder::{WasmBuilder, WasmLocal, WasmLocalI64};
|
||||
|
||||
pub fn gen_add_cs_offset(ctx: &mut JitContext) {
|
||||
if !ctx.cpu.has_flat_segmentation() {
|
||||
|
|
@ -2620,7 +2621,7 @@ pub fn gen_condition_fn(ctx: &mut JitContext, condition: u8) {
|
|||
pub fn gen_move_registers_from_locals_to_memory(ctx: &mut JitContext) {
|
||||
if cfg!(feature = "profiler") {
|
||||
let instruction = memory::read32s(ctx.start_of_current_instruction) as u32;
|
||||
::opstats::gen_opstat_unguarded_register(ctx.builder, instruction);
|
||||
opstats::gen_opstat_unguarded_register(ctx.builder, instruction);
|
||||
}
|
||||
|
||||
for i in 0..8 {
|
||||
|
|
@ -2633,7 +2634,7 @@ pub fn gen_move_registers_from_locals_to_memory(ctx: &mut JitContext) {
|
|||
pub fn gen_move_registers_from_memory_to_locals(ctx: &mut JitContext) {
|
||||
if cfg!(feature = "profiler") {
|
||||
let instruction = memory::read32s(ctx.start_of_current_instruction) as u32;
|
||||
::opstats::gen_opstat_unguarded_register(ctx.builder, instruction);
|
||||
opstats::gen_opstat_unguarded_register(ctx.builder, instruction);
|
||||
}
|
||||
|
||||
for i in 0..8 {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ use std::collections::HashSet;
|
|||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::iter;
|
||||
|
||||
use jit::{BasicBlock, BasicBlockType, MAX_EXTRA_BASIC_BLOCKS};
|
||||
use profiler;
|
||||
use crate::jit::{BasicBlock, BasicBlockType, MAX_EXTRA_BASIC_BLOCKS};
|
||||
use crate::profiler;
|
||||
|
||||
const ENTRY_NODE_ID: u32 = 0xffff_ffff;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use cpu::cpu::*;
|
||||
use cpu::global_pointers::*;
|
||||
use cpu::memory::{read8, write8};
|
||||
use cpu::misc_instr::{getaf, getcf, getzf};
|
||||
use crate::cpu::cpu::*;
|
||||
use crate::cpu::global_pointers::*;
|
||||
use crate::cpu::memory;
|
||||
use crate::cpu::misc_instr::{getaf, getcf, getzf};
|
||||
|
||||
fn int_log2(x: i32) -> i32 { 31 - x.leading_zeros() as i32 }
|
||||
|
||||
|
|
@ -1019,27 +1019,27 @@ pub unsafe fn bt_mem(virt_addr: i32, mut bit_offset: i32) {
|
|||
}
|
||||
pub unsafe fn btc_mem(virt_addr: i32, mut bit_offset: i32) {
|
||||
let phys_addr = return_on_pagefault!(translate_address_write(virt_addr + (bit_offset >> 3)));
|
||||
let bit_base = read8(phys_addr);
|
||||
let bit_base = memory::read8(phys_addr);
|
||||
bit_offset &= 7;
|
||||
*flags = *flags & !1 | bit_base >> bit_offset & 1;
|
||||
*flags_changed &= !1;
|
||||
write8(phys_addr, bit_base ^ 1 << bit_offset);
|
||||
memory::write8(phys_addr, bit_base ^ 1 << bit_offset);
|
||||
}
|
||||
pub unsafe fn btr_mem(virt_addr: i32, mut bit_offset: i32) {
|
||||
let phys_addr = return_on_pagefault!(translate_address_write(virt_addr + (bit_offset >> 3)));
|
||||
let bit_base = read8(phys_addr);
|
||||
let bit_base = memory::read8(phys_addr);
|
||||
bit_offset &= 7;
|
||||
*flags = *flags & !1 | bit_base >> bit_offset & 1;
|
||||
*flags_changed &= !1;
|
||||
write8(phys_addr, bit_base & !(1 << bit_offset));
|
||||
memory::write8(phys_addr, bit_base & !(1 << bit_offset));
|
||||
}
|
||||
pub unsafe fn bts_mem(virt_addr: i32, mut bit_offset: i32) {
|
||||
let phys_addr = return_on_pagefault!(translate_address_write(virt_addr + (bit_offset >> 3)));
|
||||
let bit_base = read8(phys_addr);
|
||||
let bit_base = memory::read8(phys_addr);
|
||||
bit_offset &= 7;
|
||||
*flags = *flags & !1 | bit_base >> bit_offset & 1;
|
||||
*flags_changed &= !1;
|
||||
write8(phys_addr, bit_base | 1 << bit_offset);
|
||||
memory::write8(phys_addr, bit_base | 1 << bit_offset);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
|
|
|||
|
|
@ -18,27 +18,28 @@ extern "C" {
|
|||
pub fn io_port_write32(port: i32, value: i32);
|
||||
}
|
||||
|
||||
use config;
|
||||
use cpu::fpu::fpu_set_tag_word;
|
||||
use cpu::global_pointers::*;
|
||||
use cpu::memory;
|
||||
use cpu::memory::mem8;
|
||||
use cpu::memory::{in_mapped_range, read128, read16, read32s, read64s, read8, write8};
|
||||
use cpu::misc_instr::{
|
||||
use crate::config;
|
||||
use crate::cpu::fpu::fpu_set_tag_word;
|
||||
use crate::cpu::global_pointers::*;
|
||||
use crate::cpu::memory;
|
||||
use crate::cpu::misc_instr::{
|
||||
adjust_stack_reg, get_stack_pointer, getaf, getcf, getof, getpf, getsf, getzf, pop16, pop32s,
|
||||
push16, push32,
|
||||
};
|
||||
use cpu::modrm::{resolve_modrm16, resolve_modrm32};
|
||||
use cpu::pic;
|
||||
use jit;
|
||||
use jit::is_near_end_of_page;
|
||||
use page::Page;
|
||||
use paging::OrPageFault;
|
||||
use prefix;
|
||||
use profiler;
|
||||
use profiler::stat::*;
|
||||
use state_flags::CachedStateFlags;
|
||||
pub use util::dbg_trace;
|
||||
use crate::cpu::modrm::{resolve_modrm16, resolve_modrm32};
|
||||
use crate::cpu::pic;
|
||||
use crate::gen;
|
||||
use crate::jit;
|
||||
use crate::jit::is_near_end_of_page;
|
||||
use crate::opstats;
|
||||
use crate::page::Page;
|
||||
use crate::paging::OrPageFault;
|
||||
use crate::prefix;
|
||||
use crate::profiler;
|
||||
use crate::profiler::stat;
|
||||
use crate::softfloat;
|
||||
use crate::state_flags::CachedStateFlags;
|
||||
use crate::util::dbg_trace;
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::ptr;
|
||||
|
|
@ -454,7 +455,7 @@ unsafe fn get_tss_ss_esp(dpl: u8) -> OrPageFault<(i32, i32)> {
|
|||
*segment_offsets.offset(TR as isize) + tss_stack_offset as i32,
|
||||
)?;
|
||||
dbg_assert!(addr & 0xFFF <= 0x1000 - 6);
|
||||
(read16(addr + 4), read32s(addr))
|
||||
(memory::read16(addr + 4), memory::read32s(addr))
|
||||
}
|
||||
else {
|
||||
let tss_stack_offset = ((dpl << 2) + 2) as u32;
|
||||
|
|
@ -465,7 +466,7 @@ unsafe fn get_tss_ss_esp(dpl: u8) -> OrPageFault<(i32, i32)> {
|
|||
*segment_offsets.offset(TR as isize) + tss_stack_offset as i32,
|
||||
)?;
|
||||
dbg_assert!(addr & 0xFFF <= 0x1000 - 4);
|
||||
(read16(addr + 2), read16(addr))
|
||||
(memory::read16(addr + 2), memory::read16(addr))
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -788,7 +789,7 @@ pub unsafe fn call_interrupt_vector(
|
|||
*idtr_offset + (interrupt_nr << 3)
|
||||
));
|
||||
|
||||
let descriptor = InterruptDescriptor::of_u64(read64s(descriptor_address) as u64);
|
||||
let descriptor = InterruptDescriptor::of_u64(memory::read64s(descriptor_address) as u64);
|
||||
|
||||
let mut offset = descriptor.offset();
|
||||
let selector = descriptor.selector() as i32;
|
||||
|
|
@ -1061,8 +1062,8 @@ pub unsafe fn call_interrupt_vector(
|
|||
// call 4 byte cs:ip interrupt vector from ivt at cpu.memory 0
|
||||
|
||||
let index = (interrupt_nr << 2) as u32;
|
||||
let new_ip = read16(index);
|
||||
let new_cs = read16(index + 2);
|
||||
let new_ip = memory::read16(index);
|
||||
let new_cs = memory::read16(index + 2);
|
||||
|
||||
dbg_assert!(
|
||||
index | 3 <= IVT_SIZE,
|
||||
|
|
@ -1917,7 +1918,7 @@ pub unsafe fn do_page_walk(
|
|||
global = false
|
||||
}
|
||||
else {
|
||||
profiler::stat_increment(TLB_MISS);
|
||||
profiler::stat_increment(stat::TLB_MISS);
|
||||
|
||||
let pae = cr4 & CR4_PAE != 0;
|
||||
|
||||
|
|
@ -1932,7 +1933,7 @@ pub unsafe fn do_page_walk(
|
|||
|
||||
let page_dir_addr =
|
||||
(pdpt_entry as u32 & 0xFFFFF000) + ((((addr as u32) >> 21) & 0x1FF) << 3);
|
||||
let page_dir_entry = read64s(page_dir_addr);
|
||||
let page_dir_entry = memory::read64s(page_dir_addr);
|
||||
dbg_assert!(
|
||||
page_dir_entry as u64 & 0x7FFF_FFFF_0000_0000 == 0,
|
||||
"Unsupported: Page directory entry larger than 32 bits"
|
||||
|
|
@ -1946,7 +1947,7 @@ pub unsafe fn do_page_walk(
|
|||
}
|
||||
else {
|
||||
let page_dir_addr = *cr.offset(3) as u32 + (((addr as u32) >> 22) << 2);
|
||||
let page_dir_entry = read32s(page_dir_addr);
|
||||
let page_dir_entry = memory::read32s(page_dir_addr);
|
||||
(page_dir_addr, page_dir_entry)
|
||||
};
|
||||
|
||||
|
|
@ -1978,7 +1979,7 @@ pub unsafe fn do_page_walk(
|
|||
| if for_writing { PAGE_TABLE_DIRTY_MASK } else { 0 };
|
||||
|
||||
if side_effects && page_dir_entry != new_page_dir_entry {
|
||||
write8(page_dir_addr, new_page_dir_entry);
|
||||
memory::write8(page_dir_addr, new_page_dir_entry);
|
||||
}
|
||||
|
||||
high = if pae {
|
||||
|
|
@ -1993,7 +1994,7 @@ pub unsafe fn do_page_walk(
|
|||
let (page_table_addr, page_table_entry) = if pae {
|
||||
let page_table_addr =
|
||||
(page_dir_entry as u32 & 0xFFFFF000) + (((addr as u32 >> 12) & 0x1FF) << 3);
|
||||
let page_table_entry = read64s(page_table_addr);
|
||||
let page_table_entry = memory::read64s(page_table_addr);
|
||||
dbg_assert!(
|
||||
page_table_entry as u64 & 0x7FFF_FFFF_0000_0000 == 0,
|
||||
"Unsupported: Page table entry larger than 32 bits"
|
||||
|
|
@ -2008,7 +2009,7 @@ pub unsafe fn do_page_walk(
|
|||
else {
|
||||
let page_table_addr =
|
||||
(page_dir_entry as u32 & 0xFFFFF000) + (((addr as u32 >> 12) & 0x3FF) << 2);
|
||||
let page_table_entry = read32s(page_table_addr);
|
||||
let page_table_entry = memory::read32s(page_table_addr);
|
||||
(page_table_addr, page_table_entry)
|
||||
};
|
||||
|
||||
|
|
@ -2030,13 +2031,13 @@ pub unsafe fn do_page_walk(
|
|||
// Note: dirty bit is only set on the page table entry
|
||||
let new_page_dir_entry = page_dir_entry | PAGE_TABLE_ACCESSED_MASK;
|
||||
if side_effects && new_page_dir_entry != page_dir_entry {
|
||||
write8(page_dir_addr, new_page_dir_entry);
|
||||
memory::write8(page_dir_addr, new_page_dir_entry);
|
||||
}
|
||||
let new_page_table_entry = page_table_entry
|
||||
| PAGE_TABLE_ACCESSED_MASK
|
||||
| if for_writing { PAGE_TABLE_DIRTY_MASK } else { 0 };
|
||||
if side_effects && page_table_entry != new_page_table_entry {
|
||||
write8(page_table_addr, new_page_table_entry);
|
||||
memory::write8(page_table_addr, new_page_table_entry);
|
||||
}
|
||||
|
||||
high = page_table_entry as u32 & 0xFFFFF000;
|
||||
|
|
@ -2046,11 +2047,11 @@ pub unsafe fn do_page_walk(
|
|||
|
||||
if side_effects && tlb_data[page as usize] == 0 {
|
||||
if valid_tlb_entries_count == VALID_TLB_ENTRY_MAX {
|
||||
profiler::stat_increment(TLB_FULL);
|
||||
profiler::stat_increment(stat::TLB_FULL);
|
||||
clear_tlb();
|
||||
// also clear global entries if tlb is almost full after clearing non-global pages
|
||||
if valid_tlb_entries_count > VALID_TLB_ENTRY_MAX * 3 / 4 {
|
||||
profiler::stat_increment(TLB_GLOBAL_FULL);
|
||||
profiler::stat_increment(stat::TLB_GLOBAL_FULL);
|
||||
full_clear_tlb();
|
||||
}
|
||||
}
|
||||
|
|
@ -2072,7 +2073,7 @@ pub unsafe fn do_page_walk(
|
|||
dbg_assert!(found);
|
||||
}
|
||||
|
||||
let is_in_mapped_range = in_mapped_range(high);
|
||||
let is_in_mapped_range = memory::in_mapped_range(high);
|
||||
let has_code = if side_effects {
|
||||
!is_in_mapped_range && jit::jit_page_has_code(Page::page_of(high))
|
||||
}
|
||||
|
|
@ -2110,7 +2111,7 @@ pub unsafe fn do_page_walk(
|
|||
|
||||
#[no_mangle]
|
||||
pub unsafe fn full_clear_tlb() {
|
||||
profiler::stat_increment(FULL_CLEAR_TLB);
|
||||
profiler::stat_increment(stat::FULL_CLEAR_TLB);
|
||||
// clear tlb including global pages
|
||||
*last_virt_eip = -1;
|
||||
for i in 0..valid_tlb_entries_count {
|
||||
|
|
@ -2130,7 +2131,7 @@ pub unsafe fn full_clear_tlb() {
|
|||
|
||||
#[no_mangle]
|
||||
pub unsafe fn clear_tlb() {
|
||||
profiler::stat_increment(CLEAR_TLB);
|
||||
profiler::stat_increment(stat::CLEAR_TLB);
|
||||
// clear tlb excluding global pages
|
||||
*last_virt_eip = -1;
|
||||
let mut global_page_offset = 0;
|
||||
|
|
@ -2226,7 +2227,7 @@ pub unsafe fn trigger_pagefault(addr: i32, present: bool, write: bool, user: boo
|
|||
);
|
||||
dbg_trace();
|
||||
}
|
||||
profiler::stat_increment(PAGE_FAULT);
|
||||
profiler::stat_increment(stat::PAGE_FAULT);
|
||||
*cr.offset(2) = addr;
|
||||
// invalidate tlb entry
|
||||
let page = ((addr as u32) >> 12) as i32;
|
||||
|
|
@ -2300,7 +2301,7 @@ pub fn check_tlb_invariants() {
|
|||
}
|
||||
|
||||
let target = (entry ^ page << 12) as u32 - unsafe { memory::mem8 } as u32;
|
||||
dbg_assert!(!in_mapped_range(target));
|
||||
dbg_assert!(!memory::in_mapped_range(target));
|
||||
|
||||
let entry_has_code = entry & TLB_HAS_CODE != 0;
|
||||
let has_code = jit::jit_page_has_code(Page::page_of(target));
|
||||
|
|
@ -2318,8 +2319,8 @@ pub unsafe fn read_imm8() -> OrPageFault<i32> {
|
|||
*eip_phys = (translate_address_read(eip)? ^ eip as u32) as i32;
|
||||
*last_virt_eip = eip & !0xFFF
|
||||
}
|
||||
dbg_assert!(!in_mapped_range((*eip_phys ^ eip) as u32));
|
||||
let data8 = *mem8.offset((*eip_phys ^ eip) as isize) as i32;
|
||||
dbg_assert!(!memory::in_mapped_range((*eip_phys ^ eip) as u32));
|
||||
let data8 = *memory::mem8.offset((*eip_phys ^ eip) as isize) as i32;
|
||||
*instruction_pointer = eip + 1;
|
||||
return Ok(data8);
|
||||
}
|
||||
|
|
@ -2336,7 +2337,7 @@ pub unsafe fn read_imm16() -> OrPageFault<i32> {
|
|||
return Ok(read_imm8()? | read_imm8()? << 8);
|
||||
}
|
||||
else {
|
||||
let data16 = read16((*eip_phys ^ *instruction_pointer) as u32);
|
||||
let data16 = memory::read16((*eip_phys ^ *instruction_pointer) as u32);
|
||||
*instruction_pointer = *instruction_pointer + 2;
|
||||
return Ok(data16);
|
||||
};
|
||||
|
|
@ -2350,7 +2351,7 @@ pub unsafe fn read_imm32s() -> OrPageFault<i32> {
|
|||
return Ok(read_imm16()? | read_imm16()? << 16);
|
||||
}
|
||||
else {
|
||||
let data32 = read32s((*eip_phys ^ *instruction_pointer) as u32);
|
||||
let data32 = memory::read32s((*eip_phys ^ *instruction_pointer) as u32);
|
||||
*instruction_pointer = *instruction_pointer + 4;
|
||||
return Ok(data32);
|
||||
};
|
||||
|
|
@ -2396,7 +2397,7 @@ pub unsafe fn lookup_segment_selector(
|
|||
|
||||
let descriptor_address = selector.descriptor_offset() as i32 + table_offset as i32;
|
||||
|
||||
let descriptor = SegmentDescriptor::of_u64(read64s(translate_address_system_read(
|
||||
let descriptor = SegmentDescriptor::of_u64(memory::read64s(translate_address_system_read(
|
||||
descriptor_address,
|
||||
)?) as u64);
|
||||
|
||||
|
|
@ -2705,7 +2706,7 @@ pub unsafe fn set_cr3(mut cr3: i32) {
|
|||
pub unsafe fn load_pdpte(cr3: i32) {
|
||||
dbg_assert!(cr3 & 0b1111 == 0);
|
||||
for i in 0..4 {
|
||||
let mut pdpt_entry = read64s(cr3 as u32 + 8 * i as u32) as u64;
|
||||
let mut pdpt_entry = memory::read64s(cr3 as u32 + 8 * i as u32) as u64;
|
||||
pdpt_entry &= !0b1110_0000_0000;
|
||||
dbg_assert!(pdpt_entry & 0b11000 == 0, "TODO");
|
||||
dbg_assert!(
|
||||
|
|
@ -2745,7 +2746,7 @@ pub unsafe fn test_privileges_for_io(port: i32, size: i32) -> bool {
|
|||
if tsr_size >= 0x67 {
|
||||
dbg_assert!(tsr_offset + 0x64 + 2 & 0xFFF < 0xFFF);
|
||||
|
||||
let iomap_base = read16(return_on_pagefault!(
|
||||
let iomap_base = memory::read16(return_on_pagefault!(
|
||||
translate_address_system_read(tsr_offset + 0x64 + 2),
|
||||
false
|
||||
));
|
||||
|
|
@ -2757,7 +2758,8 @@ pub unsafe fn test_privileges_for_io(port: i32, size: i32) -> bool {
|
|||
translate_address_system_read(tsr_offset + iomap_base + (port >> 3)),
|
||||
false
|
||||
);
|
||||
let port_info = if mask & 0xFF00 != 0 { read16(addr) } else { read8(addr) };
|
||||
let port_info =
|
||||
if mask & 0xFF00 != 0 { memory::read16(addr) } else { memory::read8(addr) };
|
||||
|
||||
dbg_assert!(addr & 0xFFF < 0xFFF);
|
||||
|
||||
|
|
@ -2852,12 +2854,12 @@ pub unsafe fn modrm_resolve(modrm_byte: i32) -> OrPageFault<i32> {
|
|||
}
|
||||
}
|
||||
|
||||
pub unsafe fn run_instruction(opcode: i32) { ::gen::interpreter::run(opcode as u32) }
|
||||
pub unsafe fn run_instruction0f_16(opcode: i32) { ::gen::interpreter0f::run(opcode as u32) }
|
||||
pub unsafe fn run_instruction0f_32(opcode: i32) { ::gen::interpreter0f::run(opcode as u32 | 0x100) }
|
||||
pub unsafe fn run_instruction(opcode: i32) { gen::interpreter::run(opcode as u32) }
|
||||
pub unsafe fn run_instruction0f_16(opcode: i32) { gen::interpreter0f::run(opcode as u32) }
|
||||
pub unsafe fn run_instruction0f_32(opcode: i32) { gen::interpreter0f::run(opcode as u32 | 0x100) }
|
||||
|
||||
pub unsafe fn cycle_internal() {
|
||||
profiler::stat_increment(CYCLE_INTERNAL);
|
||||
profiler::stat_increment(stat::CYCLE_INTERNAL);
|
||||
let mut jit_entry = None;
|
||||
let initial_eip = *instruction_pointer;
|
||||
let initial_state_flags = *state_flags;
|
||||
|
|
@ -2874,27 +2876,27 @@ pub unsafe fn cycle_internal() {
|
|||
}
|
||||
else {
|
||||
profiler::stat_increment(if is_near_end_of_page(initial_eip as u32) {
|
||||
RUN_INTERPRETED_NEAR_END_OF_PAGE
|
||||
stat::RUN_INTERPRETED_NEAR_END_OF_PAGE
|
||||
}
|
||||
else {
|
||||
RUN_INTERPRETED_PAGE_HAS_CODE
|
||||
stat::RUN_INTERPRETED_PAGE_HAS_CODE
|
||||
})
|
||||
}
|
||||
}
|
||||
else {
|
||||
profiler::stat_increment(RUN_INTERPRETED_DIFFERENT_STATE);
|
||||
profiler::stat_increment(stat::RUN_INTERPRETED_DIFFERENT_STATE);
|
||||
let s = *state_flags;
|
||||
if c.state_flags.cpl3() != s.cpl3() {
|
||||
profiler::stat_increment(RUN_INTERPRETED_DIFFERENT_STATE_CPL3);
|
||||
profiler::stat_increment(stat::RUN_INTERPRETED_DIFFERENT_STATE_CPL3);
|
||||
}
|
||||
if c.state_flags.has_flat_segmentation() != s.has_flat_segmentation() {
|
||||
profiler::stat_increment(RUN_INTERPRETED_DIFFERENT_STATE_FLAT);
|
||||
profiler::stat_increment(stat::RUN_INTERPRETED_DIFFERENT_STATE_FLAT);
|
||||
}
|
||||
if c.state_flags.is_32() != s.is_32() {
|
||||
profiler::stat_increment(RUN_INTERPRETED_DIFFERENT_STATE_IS32);
|
||||
profiler::stat_increment(stat::RUN_INTERPRETED_DIFFERENT_STATE_IS32);
|
||||
}
|
||||
if c.state_flags.ssize_32() != s.ssize_32() {
|
||||
profiler::stat_increment(RUN_INTERPRETED_DIFFERENT_STATE_SS32);
|
||||
profiler::stat_increment(stat::RUN_INTERPRETED_DIFFERENT_STATE_SS32);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -2911,7 +2913,7 @@ pub unsafe fn cycle_internal() {
|
|||
},
|
||||
}
|
||||
}
|
||||
profiler::stat_increment(RUN_FROM_CACHE);
|
||||
profiler::stat_increment(stat::RUN_FROM_CACHE);
|
||||
let initial_instruction_counter = *instruction_counter;
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
|
|
@ -2926,7 +2928,7 @@ pub unsafe fn cycle_internal() {
|
|||
in_jit = false;
|
||||
}
|
||||
profiler::stat_increment_by(
|
||||
RUN_FROM_CACHE_STEPS,
|
||||
stat::RUN_FROM_CACHE_STEPS,
|
||||
(*instruction_counter - initial_instruction_counter) as u64,
|
||||
);
|
||||
dbg_assert!(
|
||||
|
|
@ -2942,24 +2944,24 @@ pub unsafe fn cycle_internal() {
|
|||
#[allow(static_mut_refs)]
|
||||
let last_jump_addr = debug_last_jump.phys_address().unwrap();
|
||||
let last_jump_opcode = if last_jump_addr != 0 {
|
||||
read32s(last_jump_addr)
|
||||
memory::read32s(last_jump_addr)
|
||||
}
|
||||
else {
|
||||
// Happens during exit due to loop iteration limit
|
||||
0
|
||||
};
|
||||
|
||||
::opstats::record_opstat_jit_exit(last_jump_opcode as u32);
|
||||
opstats::record_opstat_jit_exit(last_jump_opcode as u32);
|
||||
}
|
||||
|
||||
if is_near_end_of_page(*instruction_pointer as u32) {
|
||||
profiler::stat_increment(RUN_FROM_CACHE_EXIT_NEAR_END_OF_PAGE);
|
||||
profiler::stat_increment(stat::RUN_FROM_CACHE_EXIT_NEAR_END_OF_PAGE);
|
||||
}
|
||||
else if Page::page_of(initial_eip as u32) == Page::page_of(*instruction_pointer as u32) {
|
||||
profiler::stat_increment(RUN_FROM_CACHE_EXIT_SAME_PAGE);
|
||||
profiler::stat_increment(stat::RUN_FROM_CACHE_EXIT_SAME_PAGE);
|
||||
}
|
||||
else {
|
||||
profiler::stat_increment(RUN_FROM_CACHE_EXIT_DIFFERENT_PAGE);
|
||||
profiler::stat_increment(stat::RUN_FROM_CACHE_EXIT_DIFFERENT_PAGE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -2974,7 +2976,7 @@ pub unsafe fn cycle_internal() {
|
|||
if initial_state_flags == c.state_flags
|
||||
&& c.state_table[initial_eip as usize & 0xFFF] != u16::MAX
|
||||
{
|
||||
profiler::stat_increment(RUN_INTERPRETED_PAGE_HAS_ENTRY_AFTER_PAGE_WALK);
|
||||
profiler::stat_increment(stat::RUN_INTERPRETED_PAGE_HAS_ENTRY_AFTER_PAGE_WALK);
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
|
@ -2999,7 +3001,7 @@ pub unsafe fn cycle_internal() {
|
|||
);
|
||||
|
||||
profiler::stat_increment_by(
|
||||
RUN_INTERPRETED_STEPS,
|
||||
stat::RUN_INTERPRETED_STEPS,
|
||||
(*instruction_counter - initial_instruction_counter) as u64,
|
||||
);
|
||||
dbg_assert!(
|
||||
|
|
@ -3016,13 +3018,13 @@ pub unsafe fn get_phys_eip() -> OrPageFault<u32> {
|
|||
*last_virt_eip = eip & !0xFFF
|
||||
}
|
||||
let phys_addr = (*eip_phys ^ eip) as u32;
|
||||
dbg_assert!(!in_mapped_range(phys_addr));
|
||||
dbg_assert!(!memory::in_mapped_range(phys_addr));
|
||||
return Ok(phys_addr);
|
||||
}
|
||||
|
||||
unsafe fn jit_run_interpreted(mut phys_addr: u32) {
|
||||
profiler::stat_increment(RUN_INTERPRETED);
|
||||
dbg_assert!(!in_mapped_range(phys_addr));
|
||||
profiler::stat_increment(stat::RUN_INTERPRETED);
|
||||
dbg_assert!(!memory::in_mapped_range(phys_addr));
|
||||
|
||||
jit_block_boundary = false;
|
||||
let mut i = 0;
|
||||
|
|
@ -3031,13 +3033,15 @@ unsafe fn jit_run_interpreted(mut phys_addr: u32) {
|
|||
if CHECK_MISSED_ENTRY_POINTS {
|
||||
let entry = jit::jit_find_cache_entry(phys_addr, *state_flags);
|
||||
if entry != jit::CachedCode::NONE {
|
||||
profiler::stat_increment(RUN_INTERPRETED_MISSED_COMPILED_ENTRY_RUN_INTERPRETED);
|
||||
profiler::stat_increment(
|
||||
stat::RUN_INTERPRETED_MISSED_COMPILED_ENTRY_RUN_INTERPRETED,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
i += 1;
|
||||
let start_eip = *instruction_pointer;
|
||||
let opcode = *mem8.offset(phys_addr as isize) as i32;
|
||||
let opcode = *memory::mem8.offset(phys_addr as isize) as i32;
|
||||
*instruction_pointer += 1;
|
||||
dbg_assert!(*prefixes == 0);
|
||||
run_instruction(opcode | (*is_32 as i32) << 8);
|
||||
|
|
@ -3098,7 +3102,7 @@ pub unsafe fn segment_prefix_op(seg: i32) {
|
|||
|
||||
#[no_mangle]
|
||||
pub unsafe fn main_loop() -> f64 {
|
||||
profiler::stat_increment(MAIN_LOOP);
|
||||
profiler::stat_increment(stat::MAIN_LOOP);
|
||||
|
||||
let start = microtick();
|
||||
|
||||
|
|
@ -3107,7 +3111,7 @@ pub unsafe fn main_loop() -> f64 {
|
|||
let t = run_hardware_timers(*acpi_enabled, start);
|
||||
handle_irqs();
|
||||
if *in_hlt {
|
||||
profiler::stat_increment(MAIN_LOOP_IDLE);
|
||||
profiler::stat_increment(stat::MAIN_LOOP_IDLE);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
|
@ -3136,7 +3140,7 @@ pub unsafe fn main_loop() -> f64 {
|
|||
}
|
||||
|
||||
pub unsafe fn do_many_cycles_native() {
|
||||
profiler::stat_increment(DO_MANY_CYCLES);
|
||||
profiler::stat_increment(stat::DO_MANY_CYCLES);
|
||||
let initial_instruction_counter = *instruction_counter;
|
||||
while (*instruction_counter).wrapping_sub(initial_instruction_counter) < LOOP_COUNTER as u32
|
||||
&& !*in_hlt
|
||||
|
|
@ -3199,7 +3203,7 @@ pub unsafe fn trigger_gp(code: i32) {
|
|||
pub unsafe fn virt_boundary_read16(low: u32, high: u32) -> i32 {
|
||||
dbg_assert!(low & 0xFFF == 0xFFF);
|
||||
dbg_assert!(high & 0xFFF == 0);
|
||||
return read8(low as u32) | read8(high as u32) << 8;
|
||||
return memory::read8(low as u32) | memory::read8(high as u32) << 8;
|
||||
}
|
||||
|
||||
#[cold]
|
||||
|
|
@ -3210,61 +3214,63 @@ pub unsafe fn virt_boundary_read32s(low: u32, high: u32) -> i32 {
|
|||
if 0 != low & 1 {
|
||||
if 0 != low & 2 {
|
||||
// 0xFFF
|
||||
mid = read16(high - 2)
|
||||
mid = memory::read16(high - 2)
|
||||
}
|
||||
else {
|
||||
// 0xFFD
|
||||
mid = read16(low + 1)
|
||||
mid = memory::read16(low + 1)
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 0xFFE
|
||||
mid = virt_boundary_read16(low + 1, high - 1)
|
||||
}
|
||||
return read8(low as u32) | mid << 8 | read8(high as u32) << 24;
|
||||
return memory::read8(low as u32) | mid << 8 | memory::read8(high as u32) << 24;
|
||||
}
|
||||
|
||||
#[cold]
|
||||
pub unsafe fn virt_boundary_write16(low: u32, high: u32, value: i32) {
|
||||
dbg_assert!(low & 0xFFF == 0xFFF);
|
||||
dbg_assert!(high & 0xFFF == 0);
|
||||
write8(low as u32, value);
|
||||
write8(high as u32, value >> 8);
|
||||
memory::write8(low as u32, value);
|
||||
memory::write8(high as u32, value >> 8);
|
||||
}
|
||||
|
||||
#[cold]
|
||||
pub unsafe fn virt_boundary_write32(low: u32, high: u32, value: i32) {
|
||||
dbg_assert!(low & 0xFFF >= 0xFFD);
|
||||
dbg_assert!(high - 3 & 0xFFF == low & 0xFFF);
|
||||
write8(low as u32, value);
|
||||
memory::write8(low as u32, value);
|
||||
if 0 != low & 1 {
|
||||
if 0 != low & 2 {
|
||||
// 0xFFF
|
||||
write8((high - 2) as u32, value >> 8);
|
||||
write8((high - 1) as u32, value >> 16);
|
||||
memory::write8((high - 2) as u32, value >> 8);
|
||||
memory::write8((high - 1) as u32, value >> 16);
|
||||
}
|
||||
else {
|
||||
// 0xFFD
|
||||
write8((low + 1) as u32, value >> 8);
|
||||
write8((low + 2) as u32, value >> 16);
|
||||
memory::write8((low + 1) as u32, value >> 8);
|
||||
memory::write8((low + 2) as u32, value >> 16);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 0xFFE
|
||||
write8((low + 1) as u32, value >> 8);
|
||||
write8((high - 1) as u32, value >> 16);
|
||||
memory::write8((low + 1) as u32, value >> 8);
|
||||
memory::write8((high - 1) as u32, value >> 16);
|
||||
}
|
||||
write8(high as u32, value >> 24);
|
||||
memory::write8(high as u32, value >> 24);
|
||||
}
|
||||
|
||||
pub unsafe fn safe_read8(addr: i32) -> OrPageFault<i32> { Ok(read8(translate_address_read(addr)?)) }
|
||||
pub unsafe fn safe_read8(addr: i32) -> OrPageFault<i32> {
|
||||
Ok(memory::read8(translate_address_read(addr)?))
|
||||
}
|
||||
|
||||
pub unsafe fn safe_read16(addr: i32) -> OrPageFault<i32> {
|
||||
if addr & 0xFFF == 0xFFF {
|
||||
Ok(safe_read8(addr)? | safe_read8(addr + 1)? << 8)
|
||||
}
|
||||
else {
|
||||
Ok(read16(translate_address_read(addr)?))
|
||||
Ok(memory::read16(translate_address_read(addr)?))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3273,7 +3279,7 @@ pub unsafe fn safe_read32s(addr: i32) -> OrPageFault<i32> {
|
|||
Ok(safe_read16(addr)? | safe_read16(addr + 2)? << 16)
|
||||
}
|
||||
else {
|
||||
Ok(read32s(translate_address_read(addr)?))
|
||||
Ok(memory::read32s(translate_address_read(addr)?))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3286,7 +3292,7 @@ pub unsafe fn safe_read64s(addr: i32) -> OrPageFault<u64> {
|
|||
Ok(safe_read32s(addr)? as u32 as u64 | (safe_read32s(addr + 4)? as u32 as u64) << 32)
|
||||
}
|
||||
else {
|
||||
Ok(read64s(translate_address_read(addr)?) as u64)
|
||||
Ok(memory::read64s(translate_address_read(addr)?) as u64)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3297,7 +3303,7 @@ pub unsafe fn safe_read128s(addr: i32) -> OrPageFault<reg128> {
|
|||
})
|
||||
}
|
||||
else {
|
||||
Ok(read128(translate_address_read(addr)?))
|
||||
Ok(memory::read128(translate_address_read(addr)?))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3428,15 +3434,15 @@ pub unsafe fn safe_read_slow_jit(
|
|||
dbg_assert!(scratch & 0xFFF == 0);
|
||||
|
||||
for s in addr_low..((addr_low | 0xFFF) + 1) {
|
||||
*(scratch as *mut u8).offset((s & 0xFFF) as isize) = read8(s) as u8
|
||||
*(scratch as *mut u8).offset((s & 0xFFF) as isize) = memory::read8(s) as u8
|
||||
}
|
||||
for s in addr_high..(addr_high + (addr + bitsize / 8 & 0xFFF) as u32) {
|
||||
*(scratch as *mut u8).offset((0x1000 | s & 0xFFF) as isize) = read8(s) as u8
|
||||
*(scratch as *mut u8).offset((0x1000 | s & 0xFFF) as isize) = memory::read8(s) as u8
|
||||
}
|
||||
|
||||
((scratch as i32) ^ addr) & !0xFFF
|
||||
}
|
||||
else if in_mapped_range(addr_low) {
|
||||
else if memory::in_mapped_range(addr_low) {
|
||||
let scratch = &raw mut jit_paging_scratch_buffer.0[0];
|
||||
|
||||
match bitsize {
|
||||
|
|
@ -3498,7 +3504,7 @@ pub unsafe fn get_phys_eip_slow_jit(addr: i32) -> i32 {
|
|||
match translate_address_read_jit(addr) {
|
||||
Err(()) => 1,
|
||||
Ok(addr_low) => {
|
||||
dbg_assert!(!in_mapped_range(addr_low as u32)); // same assumption as in read_imm8
|
||||
dbg_assert!(!memory::in_mapped_range(addr_low as u32)); // same assumption as in read_imm8
|
||||
((addr_low as i32 + memory::mem8 as i32) ^ addr) & !0xFFF
|
||||
},
|
||||
}
|
||||
|
|
@ -3587,7 +3593,7 @@ pub unsafe fn safe_write_slow_jit(
|
|||
dbg_assert!(scratch & 0xFFF == 0);
|
||||
((scratch as i32) ^ addr) & !0xFFF
|
||||
}
|
||||
else if in_mapped_range(addr_low) {
|
||||
else if memory::in_mapped_range(addr_low) {
|
||||
match bitsize {
|
||||
128 => memory::mmap_write128(addr_low, value_low, value_high),
|
||||
64 => memory::mmap_write64(addr_low, value_low),
|
||||
|
|
@ -3639,7 +3645,7 @@ pub unsafe fn safe_write128_slow_jit(
|
|||
|
||||
pub unsafe fn safe_write8(addr: i32, value: i32) -> OrPageFault<()> {
|
||||
let (phys_addr, can_skip_dirty_page) = translate_address_write_and_can_skip_dirty(addr)?;
|
||||
if in_mapped_range(phys_addr) {
|
||||
if memory::in_mapped_range(phys_addr) {
|
||||
memory::mmap_write8(phys_addr, value);
|
||||
}
|
||||
else {
|
||||
|
|
@ -3659,7 +3665,7 @@ pub unsafe fn safe_write16(addr: i32, value: i32) -> OrPageFault<()> {
|
|||
if addr & 0xFFF == 0xFFF {
|
||||
virt_boundary_write16(phys_addr, translate_address_write(addr + 1)?, value);
|
||||
}
|
||||
else if in_mapped_range(phys_addr) {
|
||||
else if memory::in_mapped_range(phys_addr) {
|
||||
memory::mmap_write16(phys_addr, value);
|
||||
}
|
||||
else {
|
||||
|
|
@ -3683,7 +3689,7 @@ pub unsafe fn safe_write32(addr: i32, value: i32) -> OrPageFault<()> {
|
|||
value,
|
||||
);
|
||||
}
|
||||
else if in_mapped_range(phys_addr) {
|
||||
else if memory::in_mapped_range(phys_addr) {
|
||||
memory::mmap_write32(phys_addr, value);
|
||||
}
|
||||
else {
|
||||
|
|
@ -3706,7 +3712,7 @@ pub unsafe fn safe_write64(addr: i32, value: u64) -> OrPageFault<()> {
|
|||
}
|
||||
else {
|
||||
let (phys_addr, can_skip_dirty_page) = translate_address_write_and_can_skip_dirty(addr)?;
|
||||
if in_mapped_range(phys_addr) {
|
||||
if memory::in_mapped_range(phys_addr) {
|
||||
memory::mmap_write64(phys_addr, value);
|
||||
}
|
||||
else {
|
||||
|
|
@ -3730,7 +3736,7 @@ pub unsafe fn safe_write128(addr: i32, value: reg128) -> OrPageFault<()> {
|
|||
}
|
||||
else {
|
||||
let (phys_addr, can_skip_dirty_page) = translate_address_write_and_can_skip_dirty(addr)?;
|
||||
if in_mapped_range(phys_addr) {
|
||||
if memory::in_mapped_range(phys_addr) {
|
||||
memory::mmap_write128(phys_addr, value.u64[0], value.u64[1]);
|
||||
}
|
||||
else {
|
||||
|
|
@ -4124,19 +4130,19 @@ pub unsafe fn get_opstats_buffer(
|
|||
| (is_mem as usize) << 3
|
||||
| fixed_g as usize;
|
||||
(if compiled {
|
||||
::opstats::opstats_compiled_buffer[index]
|
||||
opstats::opstats_compiled_buffer[index]
|
||||
}
|
||||
else if jit_exit {
|
||||
::opstats::opstats_jit_exit_buffer[index]
|
||||
opstats::opstats_jit_exit_buffer[index]
|
||||
}
|
||||
else if unguarded_register {
|
||||
::opstats::opstats_unguarded_register_buffer[index]
|
||||
opstats::opstats_unguarded_register_buffer[index]
|
||||
}
|
||||
else if wasm_size {
|
||||
::opstats::opstats_wasm_size[index]
|
||||
opstats::opstats_wasm_size[index]
|
||||
}
|
||||
else {
|
||||
::opstats::opstats_buffer[index]
|
||||
opstats::opstats_buffer[index]
|
||||
}) as f64
|
||||
}
|
||||
}
|
||||
|
|
@ -4319,7 +4325,7 @@ pub unsafe fn reset_cpu() {
|
|||
|
||||
write_xmm128_2(i as i32, 0, 0);
|
||||
|
||||
*fpu_st.offset(i) = ::softfloat::F80::ZERO;
|
||||
*fpu_st.offset(i) = softfloat::F80::ZERO;
|
||||
}
|
||||
*segment_access_bytes.offset(CS as isize) = 0x80 | (0 << 5) | 0x10 | 0x08 | 0x02; // P dpl0 S E RW
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use cpu::cpu::*;
|
||||
use cpu::global_pointers::*;
|
||||
use paging::OrPageFault;
|
||||
use softfloat::{Precision, RoundingMode, F80};
|
||||
use crate::cpu::cpu::*;
|
||||
use crate::cpu::global_pointers::*;
|
||||
use crate::paging::OrPageFault;
|
||||
use crate::softfloat::{Precision, RoundingMode, F80};
|
||||
|
||||
use std::f64;
|
||||
|
||||
const FPU_C0: u16 = 0x100;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
#![allow(non_upper_case_globals)]
|
||||
|
||||
use cpu::cpu::reg128;
|
||||
use softfloat::F80;
|
||||
use state_flags::CachedStateFlags;
|
||||
use crate::cpu::cpu::reg128;
|
||||
use crate::softfloat::F80;
|
||||
use crate::state_flags::CachedStateFlags;
|
||||
|
||||
pub const reg8: *mut u8 = 64 as *mut u8;
|
||||
pub const reg16: *mut u16 = 64 as *mut u16;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
#![allow(non_snake_case)]
|
||||
|
||||
use cpu::arith::*;
|
||||
use cpu::cpu::*;
|
||||
use cpu::fpu::*;
|
||||
use cpu::global_pointers::*;
|
||||
use cpu::misc_instr::*;
|
||||
use cpu::misc_instr::{pop16, pop32s, push16, push32};
|
||||
use cpu::string::*;
|
||||
use prefix;
|
||||
use softfloat::F80;
|
||||
use crate::cpu::arith::*;
|
||||
use crate::cpu::cpu::*;
|
||||
use crate::cpu::fpu::*;
|
||||
use crate::cpu::global_pointers::*;
|
||||
use crate::cpu::misc_instr::*;
|
||||
use crate::cpu::string::*;
|
||||
use crate::prefix;
|
||||
use crate::softfloat::F80;
|
||||
|
||||
pub unsafe fn instr_00_mem(addr: i32, r: i32) { safe_read_write8(addr, &|x| add8(x, read_reg8(r))) }
|
||||
pub unsafe fn instr_00_reg(r1: i32, r: i32) { write_reg8(r1, add8(read_reg8(r1), read_reg8(r))); }
|
||||
|
|
|
|||
|
|
@ -13,26 +13,27 @@ unsafe fn unimplemented_sse() {
|
|||
trigger_ud()
|
||||
}
|
||||
|
||||
use cpu::arith::{
|
||||
use crate::config;
|
||||
use crate::cpu::arith::{
|
||||
bsf16, bsf32, bsr16, bsr32, bt_mem, bt_reg, btc_mem, btc_reg, btr_mem, btr_reg, bts_mem,
|
||||
bts_reg, cmpxchg16, cmpxchg32, cmpxchg8, popcnt, shld16, shld32, shrd16, shrd32, xadd16,
|
||||
xadd32, xadd8,
|
||||
};
|
||||
use cpu::arith::{
|
||||
use crate::cpu::arith::{
|
||||
imul_reg16, imul_reg32, saturate_sd_to_sb, saturate_sd_to_sw, saturate_sd_to_ub,
|
||||
saturate_sw_to_sb, saturate_sw_to_ub, saturate_ud_to_ub, saturate_uw,
|
||||
};
|
||||
use cpu::cpu::*;
|
||||
use cpu::fpu::fpu_set_tag_word;
|
||||
use cpu::global_pointers::*;
|
||||
use cpu::misc_instr::{
|
||||
use crate::cpu::cpu::*;
|
||||
use crate::cpu::fpu::fpu_set_tag_word;
|
||||
use crate::cpu::global_pointers::*;
|
||||
use crate::cpu::misc_instr::{
|
||||
adjust_stack_reg, bswap, cmovcc16, cmovcc32, fxrstor, fxsave, get_stack_pointer, jmpcc16,
|
||||
jmpcc32, push16, push32_sreg, setcc_mem, setcc_reg, test_b, test_be, test_l, test_le, test_o,
|
||||
test_p, test_s, test_z,
|
||||
};
|
||||
use cpu::misc_instr::{lar, lsl, verr, verw};
|
||||
use cpu::misc_instr::{lss16, lss32};
|
||||
use cpu::sse_instr::*;
|
||||
use crate::cpu::misc_instr::{lar, lsl, verr, verw};
|
||||
use crate::cpu::misc_instr::{lss16, lss32};
|
||||
use crate::cpu::sse_instr::*;
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr16_0F00_0_mem(addr: i32) {
|
||||
|
|
@ -1202,12 +1203,12 @@ pub unsafe fn instr_0F30() {
|
|||
IA32_APIC_BASE => {
|
||||
dbg_assert!(
|
||||
high == 0,
|
||||
("Changing APIC address (high 32 bits) not supported")
|
||||
"Changing APIC address (high 32 bits) not supported"
|
||||
);
|
||||
let address = low & !(IA32_APIC_BASE_BSP | IA32_APIC_BASE_EXTD | IA32_APIC_BASE_EN);
|
||||
dbg_assert!(
|
||||
address == APIC_ADDRESS,
|
||||
("Changing APIC address not supported")
|
||||
"Changing APIC address not supported"
|
||||
);
|
||||
dbg_assert!(low & IA32_APIC_BASE_EXTD == 0, "x2apic not supported");
|
||||
*apic_enabled = low & IA32_APIC_BASE_EN == IA32_APIC_BASE_EN
|
||||
|
|
@ -3245,7 +3246,7 @@ pub unsafe fn instr_0FA2() {
|
|||
ebx = 1 << 16 | 8 << 8; // cpu count, clflush size
|
||||
ecx = 1 << 0 | 1 << 23 | 1 << 30; // sse3, popcnt, rdrand
|
||||
let vme = 0 << 1;
|
||||
if ::config::VMWARE_HYPERVISOR_PORT {
|
||||
if config::VMWARE_HYPERVISOR_PORT {
|
||||
ecx |= 1 << 31
|
||||
}; // hypervisor
|
||||
edx = (if true /* have fpu */ { 1 } else { 0 }) | // fpu
|
||||
|
|
@ -3318,7 +3319,7 @@ pub unsafe fn instr_0FA2() {
|
|||
|
||||
0x40000000 => {
|
||||
// hypervisor
|
||||
if ::config::VMWARE_HYPERVISOR_PORT {
|
||||
if config::VMWARE_HYPERVISOR_PORT {
|
||||
// h("Ware".split("").reduce((a, c, i) => a | c.charCodeAt(0) << i * 8, 0))
|
||||
ebx = 0x61774D56 | 0; // VMwa
|
||||
ecx = 0x4D566572 | 0; // reVM
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@ mod ext {
|
|||
}
|
||||
}
|
||||
|
||||
use cpu::cpu::reg128;
|
||||
use cpu::global_pointers::memory_size;
|
||||
use cpu::vga;
|
||||
use jit;
|
||||
use page::Page;
|
||||
use crate::cpu::cpu::reg128;
|
||||
use crate::cpu::global_pointers::memory_size;
|
||||
use crate::cpu::vga;
|
||||
use crate::jit;
|
||||
use crate::page::Page;
|
||||
|
||||
use std::alloc;
|
||||
use std::ptr;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
use cpu::cpu::*;
|
||||
use cpu::fpu::{
|
||||
use crate::cpu::cpu::*;
|
||||
use crate::cpu::fpu::{
|
||||
fpu_load_m80, fpu_load_status_word, fpu_set_status_word, fpu_store_m80, set_control_word,
|
||||
};
|
||||
use cpu::global_pointers::*;
|
||||
use paging::OrPageFault;
|
||||
use crate::cpu::global_pointers::*;
|
||||
use crate::paging::OrPageFault;
|
||||
|
||||
pub unsafe fn getcf() -> bool {
|
||||
if 0 != *flags_changed & 1 {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use cpu::cpu::*;
|
||||
use paging::OrPageFault;
|
||||
use crate::cpu::cpu::*;
|
||||
use crate::paging::OrPageFault;
|
||||
|
||||
pub unsafe fn resolve_modrm16(modrm_byte: i32) -> OrPageFault<i32> {
|
||||
match modrm_byte & !0o070 {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
pub const PIC_LOG: bool = false;
|
||||
pub const PIC_LOG_VERBOSE: bool = false;
|
||||
|
||||
use cpu::cpu;
|
||||
use crate::cpu::cpu;
|
||||
use std::sync::{Mutex, MutexGuard};
|
||||
|
||||
// Note: This layout is deliberately chosen to match the old JavaScript pic state
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use cpu::cpu::*;
|
||||
use cpu::global_pointers::mxcsr;
|
||||
use crate::cpu::cpu::*;
|
||||
use crate::cpu::global_pointers::mxcsr;
|
||||
|
||||
pub unsafe fn mov_r_m64(addr: i32, r: i32) {
|
||||
// mov* m64, mm
|
||||
|
|
|
|||
|
|
@ -9,22 +9,19 @@
|
|||
// ins 0 0 1/w
|
||||
// outs 0 1 0
|
||||
|
||||
use cpu::arith::{cmp16, cmp32, cmp8};
|
||||
use cpu::cpu::{
|
||||
use crate::cpu;
|
||||
use crate::cpu::arith::{cmp16, cmp32, cmp8};
|
||||
use crate::cpu::cpu::{
|
||||
get_seg, io_port_read16, io_port_read32, io_port_read8, io_port_write16, io_port_write32,
|
||||
io_port_write8, read_reg16, read_reg32, safe_read16, safe_read32s, safe_read8, safe_write16,
|
||||
safe_write32, safe_write8, set_reg_asize, test_privileges_for_io, translate_address_read,
|
||||
translate_address_write_and_can_skip_dirty, writable_or_pagefault, write_reg16, write_reg32,
|
||||
write_reg8, AL, AX, DX, EAX, ECX, EDI, ES, ESI, FLAG_DIRECTION,
|
||||
};
|
||||
use cpu::global_pointers::{flags, instruction_pointer, previous_ip};
|
||||
use cpu::memory::{
|
||||
in_mapped_range, in_svga_lfb, memcpy_into_svga_lfb, memcpy_no_mmap_or_dirty_check,
|
||||
memset_no_mmap_or_dirty_check, read16_no_mmap_check, read32_no_mmap_check, read8_no_mmap_check,
|
||||
write16_no_mmap_or_dirty_check, write32_no_mmap_or_dirty_check, write8_no_mmap_or_dirty_check,
|
||||
};
|
||||
use jit;
|
||||
use page::Page;
|
||||
use crate::cpu::global_pointers::{flags, instruction_pointer, previous_ip};
|
||||
use crate::cpu::memory;
|
||||
use crate::jit;
|
||||
use crate::page::Page;
|
||||
|
||||
fn count_until_end_of_page(direction: i32, size: i32, addr: u32) -> u32 {
|
||||
(if direction == 1 {
|
||||
|
|
@ -166,21 +163,21 @@ unsafe fn string_instruction(
|
|||
Instruction::Movs => {
|
||||
let (addr, skip) =
|
||||
return_on_pagefault!(translate_address_write_and_can_skip_dirty(es + dst));
|
||||
movs_into_svga_lfb = in_svga_lfb(addr);
|
||||
rep_fast = rep_fast && (!in_mapped_range(addr) || movs_into_svga_lfb);
|
||||
movs_into_svga_lfb = memory::in_svga_lfb(addr);
|
||||
rep_fast = rep_fast && (!memory::in_mapped_range(addr) || movs_into_svga_lfb);
|
||||
phys_dst = addr;
|
||||
skip_dirty_page = skip;
|
||||
},
|
||||
Instruction::Stos | Instruction::Ins => {
|
||||
let (addr, skip) =
|
||||
return_on_pagefault!(translate_address_write_and_can_skip_dirty(es + dst));
|
||||
rep_fast = rep_fast && !in_mapped_range(addr);
|
||||
rep_fast = rep_fast && !memory::in_mapped_range(addr);
|
||||
phys_dst = addr;
|
||||
skip_dirty_page = skip;
|
||||
},
|
||||
Instruction::Cmps | Instruction::Scas => {
|
||||
let addr = return_on_pagefault!(translate_address_read(es + dst));
|
||||
rep_fast = rep_fast && !in_mapped_range(addr);
|
||||
rep_fast = rep_fast && !memory::in_mapped_range(addr);
|
||||
phys_dst = addr;
|
||||
skip_dirty_page = true;
|
||||
},
|
||||
|
|
@ -190,7 +187,7 @@ unsafe fn string_instruction(
|
|||
match instruction {
|
||||
Instruction::Movs | Instruction::Cmps | Instruction::Lods | Instruction::Outs => {
|
||||
let addr = return_on_pagefault!(translate_address_read(ds + src));
|
||||
rep_fast = rep_fast && !in_mapped_range(addr);
|
||||
rep_fast = rep_fast && !memory::in_mapped_range(addr);
|
||||
phys_src = addr;
|
||||
},
|
||||
_ => {},
|
||||
|
|
@ -261,9 +258,9 @@ unsafe fn string_instruction(
|
|||
let src_val = match instruction {
|
||||
Instruction::Movs | Instruction::Cmps | Instruction::Lods | Instruction::Outs => {
|
||||
match size {
|
||||
Size::B => read8_no_mmap_check(phys_src),
|
||||
Size::W => read16_no_mmap_check(phys_src),
|
||||
Size::D => read32_no_mmap_check(phys_src),
|
||||
Size::B => memory::read8_no_mmap_check(phys_src),
|
||||
Size::W => memory::read16_no_mmap_check(phys_src),
|
||||
Size::D => memory::read32_no_mmap_check(phys_src),
|
||||
}
|
||||
},
|
||||
Instruction::Scas | Instruction::Stos => data & size_mask,
|
||||
|
|
@ -278,9 +275,9 @@ unsafe fn string_instruction(
|
|||
|
||||
match instruction {
|
||||
Instruction::Cmps | Instruction::Scas => match size {
|
||||
Size::B => dst_val = read8_no_mmap_check(phys_dst),
|
||||
Size::W => dst_val = read16_no_mmap_check(phys_dst),
|
||||
Size::D => dst_val = read32_no_mmap_check(phys_dst),
|
||||
Size::B => dst_val = memory::read8_no_mmap_check(phys_dst),
|
||||
Size::W => dst_val = memory::read16_no_mmap_check(phys_dst),
|
||||
Size::D => dst_val = memory::read32_no_mmap_check(phys_dst),
|
||||
},
|
||||
Instruction::Outs => match size {
|
||||
Size::B => io_port_write8(port, src_val),
|
||||
|
|
@ -293,9 +290,9 @@ unsafe fn string_instruction(
|
|||
Size::D => write_reg32(EAX, src_val),
|
||||
},
|
||||
Instruction::Ins => match size {
|
||||
Size::B => write8_no_mmap_or_dirty_check(phys_dst, src_val),
|
||||
Size::W => write16_no_mmap_or_dirty_check(phys_dst, src_val),
|
||||
Size::D => write32_no_mmap_or_dirty_check(phys_dst, src_val),
|
||||
Size::B => memory::write8_no_mmap_or_dirty_check(phys_dst, src_val),
|
||||
Size::W => memory::write16_no_mmap_or_dirty_check(phys_dst, src_val),
|
||||
Size::D => memory::write32_no_mmap_or_dirty_check(phys_dst, src_val),
|
||||
},
|
||||
Instruction::Movs => {
|
||||
if direction == -1 {
|
||||
|
|
@ -303,15 +300,15 @@ unsafe fn string_instruction(
|
|||
phys_dst -= (count_until_end_of_page - 1) * size_bytes as u32;
|
||||
}
|
||||
if movs_into_svga_lfb {
|
||||
::cpu::vga::mark_dirty(phys_dst);
|
||||
memcpy_into_svga_lfb(
|
||||
cpu::vga::mark_dirty(phys_dst);
|
||||
memory::memcpy_into_svga_lfb(
|
||||
phys_src,
|
||||
phys_dst,
|
||||
count_until_end_of_page * size_bytes as u32,
|
||||
);
|
||||
}
|
||||
else {
|
||||
memcpy_no_mmap_or_dirty_check(
|
||||
memory::memcpy_no_mmap_or_dirty_check(
|
||||
phys_src,
|
||||
phys_dst,
|
||||
count_until_end_of_page * size_bytes as u32,
|
||||
|
|
@ -325,7 +322,7 @@ unsafe fn string_instruction(
|
|||
if direction == -1 {
|
||||
phys_dst -= count_until_end_of_page - 1
|
||||
}
|
||||
memset_no_mmap_or_dirty_check(
|
||||
memory::memset_no_mmap_or_dirty_check(
|
||||
phys_dst,
|
||||
src_val as u8,
|
||||
count_until_end_of_page,
|
||||
|
|
@ -333,8 +330,8 @@ unsafe fn string_instruction(
|
|||
i = count_until_end_of_page;
|
||||
break;
|
||||
},
|
||||
Size::W => write16_no_mmap_or_dirty_check(phys_dst, src_val),
|
||||
Size::D => write32_no_mmap_or_dirty_check(phys_dst, src_val),
|
||||
Size::W => memory::write16_no_mmap_or_dirty_check(phys_dst, src_val),
|
||||
Size::D => memory::write32_no_mmap_or_dirty_check(phys_dst, src_val),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
static mut dirty_bitmap: Vec<u64> = Vec::new();
|
||||
static mut dest_buffer: Vec<u32> = Vec::new();
|
||||
|
||||
use cpu::global_pointers;
|
||||
use cpu::memory;
|
||||
use crate::cpu::global_pointers;
|
||||
use crate::cpu::memory;
|
||||
|
||||
use std::ptr;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use cpu::memory;
|
||||
use prefix::{PREFIX_MASK_ADDRSIZE, PREFIX_MASK_OPSIZE};
|
||||
use state_flags::CachedStateFlags;
|
||||
use crate::cpu::memory;
|
||||
use crate::prefix::{PREFIX_MASK_ADDRSIZE, PREFIX_MASK_OPSIZE};
|
||||
use crate::state_flags::CachedStateFlags;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CpuContext {
|
||||
|
|
|
|||
|
|
@ -30,13 +30,13 @@ macro_rules! dbg_assert {
|
|||
macro_rules! console_log {
|
||||
($fmt:expr) => {
|
||||
{
|
||||
use ::util::{ console_log_to_js_console };
|
||||
use crate::util::{ console_log_to_js_console };
|
||||
console_log_to_js_console($fmt);
|
||||
}
|
||||
};
|
||||
($fmt:expr, $($arg:tt)*) => {
|
||||
{
|
||||
use ::util::{ console_log_to_js_console };
|
||||
use crate::util::{ console_log_to_js_console };
|
||||
console_log_to_js_console(format!($fmt, $($arg)*));
|
||||
}
|
||||
};
|
||||
|
|
@ -47,13 +47,13 @@ macro_rules! console_log {
|
|||
macro_rules! dbg_log {
|
||||
($fmt:expr) => {
|
||||
{
|
||||
use ::util::{ DEBUG, log_to_js_console };
|
||||
use crate::util::{ DEBUG, log_to_js_console };
|
||||
if DEBUG { log_to_js_console($fmt); }
|
||||
}
|
||||
};
|
||||
($fmt:expr, $($arg:tt)*) => {
|
||||
{
|
||||
use ::util::{ DEBUG, log_to_js_console };
|
||||
use crate::util::{ DEBUG, log_to_js_console };
|
||||
if DEBUG { log_to_js_console(format!($fmt, $($arg)*)); }
|
||||
}
|
||||
};
|
||||
|
|
@ -63,7 +63,7 @@ macro_rules! dbg_log {
|
|||
#[allow(unused_macros)]
|
||||
macro_rules! dbg_assert {
|
||||
($cond:expr) => {{
|
||||
use util::{abort, log_to_js_console, DEBUG};
|
||||
use crate::util::{abort, log_to_js_console, DEBUG};
|
||||
if DEBUG && !$cond {
|
||||
log_to_js_console(format!(
|
||||
"Assertion failed at {}:{}:{}: '{}'",
|
||||
|
|
@ -79,7 +79,7 @@ macro_rules! dbg_assert {
|
|||
}
|
||||
}};
|
||||
($cond:expr, $desc:expr) => {{
|
||||
use util::{abort, log_to_js_console, DEBUG};
|
||||
use crate::util::{abort, log_to_js_console, DEBUG};
|
||||
if DEBUG && !$cond {
|
||||
log_to_js_console(format!(
|
||||
"Assertion failed at {}:{}:{}: '{}' - '{}'",
|
||||
|
|
|
|||
|
|
@ -5,22 +5,23 @@ use std::ops::{Deref, DerefMut};
|
|||
use std::ptr::NonNull;
|
||||
use std::sync::{Mutex, MutexGuard};
|
||||
|
||||
use analysis::AnalysisType;
|
||||
use codegen;
|
||||
use control_flow;
|
||||
use control_flow::WasmStructure;
|
||||
use cpu::cpu;
|
||||
use cpu::global_pointers;
|
||||
use cpu::memory;
|
||||
use cpu_context::CpuContext;
|
||||
use jit_instructions;
|
||||
use opstats;
|
||||
use page::Page;
|
||||
use profiler;
|
||||
use profiler::stat;
|
||||
use state_flags::CachedStateFlags;
|
||||
use util::SafeToU16;
|
||||
use wasmgen::wasm_builder::{Label, WasmBuilder, WasmLocal};
|
||||
use crate::analysis;
|
||||
use crate::analysis::AnalysisType;
|
||||
use crate::codegen;
|
||||
use crate::control_flow;
|
||||
use crate::control_flow::WasmStructure;
|
||||
use crate::cpu::cpu;
|
||||
use crate::cpu::global_pointers;
|
||||
use crate::cpu::memory;
|
||||
use crate::cpu_context::CpuContext;
|
||||
use crate::jit_instructions;
|
||||
use crate::opstats;
|
||||
use crate::page::Page;
|
||||
use crate::profiler;
|
||||
use crate::profiler::stat;
|
||||
use crate::state_flags::CachedStateFlags;
|
||||
use crate::util::SafeToU16;
|
||||
use crate::wasmgen::wasm_builder::{Label, WasmBuilder, WasmLocal};
|
||||
|
||||
#[derive(Copy, Clone, Eq, Hash, PartialEq)]
|
||||
#[repr(transparent)]
|
||||
|
|
@ -30,7 +31,7 @@ impl WasmTableIndex {
|
|||
}
|
||||
|
||||
mod unsafe_jit {
|
||||
use jit::{CachedStateFlags, WasmTableIndex};
|
||||
use super::{CachedStateFlags, WasmTableIndex};
|
||||
|
||||
extern "C" {
|
||||
pub fn codegen_finalize(
|
||||
|
|
@ -538,7 +539,7 @@ fn jit_find_basic_blocks(
|
|||
eip: current_address,
|
||||
..cpu
|
||||
};
|
||||
let analysis = ::analysis::analyze_step(&mut cpu);
|
||||
let analysis = analysis::analyze_step(&mut cpu);
|
||||
current_block.number_of_instructions += 1;
|
||||
let has_next_instruction = !analysis.no_next_instruction;
|
||||
current_address = cpu.eip;
|
||||
|
|
|
|||
|
|
@ -1,21 +1,22 @@
|
|||
#![allow(non_snake_case)]
|
||||
|
||||
use codegen;
|
||||
use codegen::{BitSize, ConditionNegate};
|
||||
use cpu::cpu::{
|
||||
use crate::codegen;
|
||||
use crate::codegen::{BitSize, ConditionNegate};
|
||||
use crate::cpu::cpu::{
|
||||
FLAGS_ALL, FLAGS_DEFAULT, FLAGS_MASK, FLAG_ADJUST, FLAG_CARRY, FLAG_DIRECTION, FLAG_INTERRUPT,
|
||||
FLAG_IOPL, FLAG_OVERFLOW, FLAG_SUB, FLAG_VM, FLAG_ZERO, OPSIZE_16, OPSIZE_32, OPSIZE_8,
|
||||
};
|
||||
use cpu::global_pointers;
|
||||
use jit::{Instruction, InstructionOperand, InstructionOperandDest, JitContext};
|
||||
use modrm::{jit_add_seg_offset, jit_add_seg_offset_no_override, ModrmByte};
|
||||
use prefix::{PREFIX_66, PREFIX_67, PREFIX_F2, PREFIX_F3};
|
||||
use prefix::{PREFIX_MASK_SEGMENT, SEG_PREFIX_ZERO};
|
||||
use regs;
|
||||
use regs::{AX, BP, BX, CX, DI, DX, SI, SP};
|
||||
use regs::{CS, DS, ES, FS, GS, SS};
|
||||
use regs::{EAX, EBP, EBX, ECX, EDI, EDX, ESI, ESP};
|
||||
use wasmgen::wasm_builder::{WasmBuilder, WasmLocal};
|
||||
use crate::cpu::global_pointers;
|
||||
use crate::gen;
|
||||
use crate::jit::{Instruction, InstructionOperand, InstructionOperandDest, JitContext};
|
||||
use crate::modrm::{jit_add_seg_offset, jit_add_seg_offset_no_override, ModrmByte};
|
||||
use crate::prefix::{PREFIX_66, PREFIX_67, PREFIX_F2, PREFIX_F3};
|
||||
use crate::prefix::{PREFIX_MASK_SEGMENT, SEG_PREFIX_ZERO};
|
||||
use crate::regs;
|
||||
use crate::regs::{AX, BP, BX, CX, DI, DX, SI, SP};
|
||||
use crate::regs::{CS, DS, ES, FS, GS, SS};
|
||||
use crate::regs::{EAX, EBP, EBX, ECX, EDI, EDX, ESI, ESP};
|
||||
use crate::wasmgen::wasm_builder::{WasmBuilder, WasmLocal};
|
||||
|
||||
enum LocalOrImmediate<'a> {
|
||||
WasmLocal(&'a WasmLocal),
|
||||
|
|
@ -75,7 +76,7 @@ fn local_to_instruction_operand(ctx: &mut JitContext, local: &WasmLocal) -> Inst
|
|||
pub fn jit_instruction(ctx: &mut JitContext, instr_flags: &mut u32) {
|
||||
ctx.cpu.prefixes = 0;
|
||||
ctx.start_of_current_instruction = ctx.cpu.eip;
|
||||
::gen::jit::jit(
|
||||
gen::jit::jit(
|
||||
ctx.cpu.read_imm8() as u32 | (ctx.cpu.osize_32() as u32) << 8,
|
||||
ctx,
|
||||
instr_flags,
|
||||
|
|
@ -83,7 +84,7 @@ pub fn jit_instruction(ctx: &mut JitContext, instr_flags: &mut u32) {
|
|||
}
|
||||
|
||||
pub fn jit_handle_prefix(ctx: &mut JitContext, instr_flags: &mut u32) {
|
||||
::gen::jit::jit(
|
||||
gen::jit::jit(
|
||||
ctx.cpu.read_imm8() as u32 | (ctx.cpu.osize_32() as u32) << 8,
|
||||
ctx,
|
||||
instr_flags,
|
||||
|
|
@ -97,10 +98,10 @@ pub fn jit_handle_segment_prefix(segment: u32, ctx: &mut JitContext, instr_flags
|
|||
}
|
||||
|
||||
pub fn instr16_0F_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
|
||||
::gen::jit0f::jit(ctx.cpu.read_imm8() as u32, ctx, instr_flags)
|
||||
gen::jit0f::jit(ctx.cpu.read_imm8() as u32, ctx, instr_flags)
|
||||
}
|
||||
pub fn instr32_0F_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
|
||||
::gen::jit0f::jit(ctx.cpu.read_imm8() as u32 | 0x100, ctx, instr_flags)
|
||||
gen::jit0f::jit(ctx.cpu.read_imm8() as u32 | 0x100, ctx, instr_flags)
|
||||
}
|
||||
pub fn instr_26_jit(ctx: &mut JitContext, instr_flags: &mut u32) {
|
||||
jit_handle_segment_prefix(ES, ctx, instr_flags)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use cpu::cpu::translate_address_system_read;
|
||||
use crate::cpu::cpu::translate_address_system_read;
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn translate_address_system_read_js(addr: i32) -> u32 {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
use codegen;
|
||||
use cpu::global_pointers;
|
||||
use cpu_context::CpuContext;
|
||||
use jit::JitContext;
|
||||
use prefix::{PREFIX_MASK_SEGMENT, SEG_PREFIX_ZERO};
|
||||
use profiler;
|
||||
use regs::{BP, BX, DI, SI};
|
||||
use regs::{CS, DS, ES, FS, GS, SS};
|
||||
use regs::{EAX, EBP, EBX, ECX, EDI, EDX, ESI, ESP};
|
||||
use crate::codegen;
|
||||
use crate::cpu::global_pointers;
|
||||
use crate::cpu_context::CpuContext;
|
||||
use crate::jit::JitContext;
|
||||
use crate::prefix::{PREFIX_MASK_SEGMENT, SEG_PREFIX_ZERO};
|
||||
use crate::profiler;
|
||||
use crate::regs::{BP, BX, DI, SI};
|
||||
use crate::regs::{CS, DS, ES, FS, GS, SS};
|
||||
use crate::regs::{EAX, EBP, EBX, ECX, EDI, EDX, ESI, ESP};
|
||||
|
||||
pub struct ModrmByte {
|
||||
segment: u32,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use wasmgen::wasm_builder::WasmBuilder;
|
||||
use crate::wasmgen::wasm_builder::WasmBuilder;
|
||||
|
||||
const SIZE: usize = if cfg!(feature = "profiler") { 8192 } else { 0 };
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
use std::collections::HashMap;
|
||||
use std::mem::transmute;
|
||||
|
||||
use leb::{
|
||||
use crate::leb::{
|
||||
write_fixed_leb16_at_idx, write_fixed_leb32_at_idx, write_leb_i32, write_leb_i64, write_leb_u32,
|
||||
};
|
||||
use std::mem::transmute;
|
||||
use util::{SafeToU16, SafeToU8};
|
||||
use wasmgen::wasm_opcodes as op;
|
||||
use crate::util::{SafeToU16, SafeToU8};
|
||||
use crate::wasmgen::wasm_opcodes as op;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
#[allow(non_camel_case_types)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue