jit RDTSC

This commit is contained in:
Fabian 2020-12-31 19:14:31 -06:00
parent 0091338c6b
commit 5dd03792c2
7 changed files with 49 additions and 1 deletions

View file

@ -460,7 +460,7 @@ const encodings = [
{ opcode: 0x0F27, skip: 1, block_boundary: 1, },
{ opcode: 0x0F30, skip: 1, block_boundary: 1, }, // wrmsr
{ opcode: 0x0F31, skip: 1, block_boundary: 1, }, // rdtsc
{ opcode: 0x0F31, skip: 1, custom: 1, }, // rdtsc
{ opcode: 0x0F32, skip: 1, block_boundary: 1, }, // rdmsr
{ opcode: 0x0F33, skip: 1, block_boundary: 1, }, // rdpmc
{ opcode: 0x0F34, skip: 1, block_boundary: 1, no_next_instruction: 1, }, // sysenter

View file

@ -310,6 +310,12 @@ pub fn gen_call_fn1_f64_ret_i32(builder: &mut WasmBuilder, name: &str) {
builder.call_fn(fn_idx);
}
pub fn gen_call_fn0_ret_i64(builder: &mut WasmBuilder, name: &str) {
// generates: fn( _ ) where _ must be left on the stack before calling this, and fn returns a value
let fn_idx = builder.get_fn_idx(name, FunctionType::FN0_RET_I64_TYPE_INDEX);
builder.call_fn(fn_idx);
}
pub fn gen_call_fn1_ret_i64(builder: &mut WasmBuilder, name: &str) {
// generates: fn( _ ) where _ must be left on the stack before calling this, and fn returns a value
let fn_idx = builder.get_fn_idx(name, FunctionType::FN1_RET_I64_TYPE_INDEX);

View file

@ -3275,6 +3275,7 @@ pub unsafe fn set_tsc(low: u32, high: u32) {
tsc_offset = current_value.wrapping_sub(new_value);
}
#[no_mangle]
pub unsafe fn read_tsc() -> u64 {
let n = microtick() * TSC_RATE;
let value = (n as u64).wrapping_sub(tsc_offset);

View file

@ -9,6 +9,7 @@ pub const PAGE_FAULT: u32 = 540;
pub const INSTRUCTION_POINTER: u32 = 556;
pub const PREVIOUS_IP: u32 = 560;
pub const CR: u32 = 580;
pub const CPL: u32 = 612;
pub const TIMESTAMP_COUNTER: u32 = 664;
pub const SREG: u32 = 668;

View file

@ -3870,6 +3870,37 @@ pub fn instr32_AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS,
pub fn instr32_F2AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 32, 0xF2) }
pub fn instr32_F3AF_jit(ctx: &mut JitContext) { gen_string_ins(ctx, String::SCAS, 32, 0xF3) }
pub fn instr_0F31_jit(ctx: &mut JitContext) {
ctx.builder.load_fixed_u8(global_pointers::CPL);
ctx.builder.eqz_i32();
dbg_assert!(regs::CR4_TSD < 0x100);
ctx.builder
.load_fixed_u8(global_pointers::get_creg_offset(4));
ctx.builder.const_i32(regs::CR4_TSD as i32);
ctx.builder.and_i32();
ctx.builder.eqz_i32();
ctx.builder.or_i32();
ctx.builder.if_void();
codegen::gen_call_fn0_ret_i64(ctx.builder, "read_tsc");
let tsc = ctx.builder.tee_new_local_i64();
ctx.builder.wrap_i64_to_i32();
codegen::gen_set_reg32(ctx, regs::EAX);
ctx.builder.get_local_i64(&tsc);
ctx.builder.const_i64(32);
ctx.builder.shr_u_i64();
ctx.builder.wrap_i64_to_i32();
codegen::gen_set_reg32(ctx, regs::EDX);
ctx.builder.free_local_i64(tsc);
ctx.builder.else_();
codegen::gen_trigger_gp(ctx, 0);
ctx.builder.block_end();
}
pub fn instr_0F18_mem_jit(ctx: &mut JitContext, modrm_byte: u8, _reg: u32) {
modrm::skip(ctx.cpu, modrm_byte);
}

View file

@ -34,3 +34,5 @@ pub const BH: u32 = 7;
pub const CR0_EM: u32 = 1 << 2;
pub const CR0_TS: u32 = 1 << 3;
pub const CR4_TSD: u32 = 1 << 2;

View file

@ -14,6 +14,7 @@ pub enum FunctionType {
FN3_TYPE_INDEX,
FN0_RET_TYPE_INDEX,
FN0_RET_I64_TYPE_INDEX,
FN1_RET_TYPE_INDEX,
FN2_RET_TYPE_INDEX,
@ -244,6 +245,12 @@ impl WasmBuilder {
self.output.push(1);
self.output.push(op::TYPE_I32);
},
FunctionType::FN0_RET_I64_TYPE_INDEX => {
self.output.push(op::TYPE_FUNC);
self.output.push(0);
self.output.push(1);
self.output.push(op::TYPE_I64);
},
FunctionType::FN1_RET_TYPE_INDEX => {
self.output.push(op::TYPE_FUNC);
self.output.push(1);