jit RDTSC
This commit is contained in:
parent
0091338c6b
commit
5dd03792c2
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue