jit cmpxchg8b
This commit is contained in:
parent
fc38676089
commit
6a18618e76
|
@ -576,7 +576,7 @@ const encodings = [
|
|||
|
||||
{ opcode: 0x0FB0, e: 1 }, // cmxchg
|
||||
{ opcode: 0x0FB1, os: 1, e: 1, custom: 1 },
|
||||
{ opcode: 0x0FC7, e: 1, fixed_g: 1, os: 1, reg_ud: 1, }, // cmpxchg8b (memory)
|
||||
{ opcode: 0x0FC7, e: 1, fixed_g: 1, os: 1, reg_ud: 1, custom: 1 }, // cmpxchg8b (memory)
|
||||
{ opcode: 0x0FC7, e: 1, fixed_g: 6, os: 1, mem_ud: 1, skip: 1, }, // rdrand
|
||||
|
||||
{ opcode: 0x0FB2, block_boundary: 1, os: 1, e: 1, skip: 1, }, // lss
|
||||
|
|
|
@ -408,6 +408,11 @@ enum GenSafeWriteValue<'a> {
|
|||
TwoI64s(&'a WasmLocalI64, &'a WasmLocalI64),
|
||||
}
|
||||
|
||||
enum GenSafeReadWriteValue {
|
||||
I32(WasmLocal),
|
||||
I64(WasmLocalI64),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
pub enum BitSize {
|
||||
BYTE,
|
||||
|
@ -840,7 +845,9 @@ pub fn gen_safe_read_write(
|
|||
BitSize::DWORD => {
|
||||
ctx.builder.call_fn2_ret("safe_read_write32s_slow_jit");
|
||||
},
|
||||
BitSize::QWORD => dbg_assert!(false),
|
||||
BitSize::QWORD => {
|
||||
ctx.builder.call_fn2_ret("safe_read_write64_slow_jit");
|
||||
},
|
||||
BitSize::DQWORD => dbg_assert!(false),
|
||||
}
|
||||
ctx.builder.tee_local(&entry_local);
|
||||
|
@ -886,14 +893,23 @@ pub fn gen_safe_read_write(
|
|||
BitSize::DWORD => {
|
||||
ctx.builder.load_unaligned_i32(0);
|
||||
},
|
||||
BitSize::QWORD => assert!(false), // not used
|
||||
BitSize::QWORD => {
|
||||
ctx.builder.load_unaligned_i64(0);
|
||||
},
|
||||
BitSize::DQWORD => assert!(false), // not used
|
||||
}
|
||||
|
||||
// value is now on stack
|
||||
|
||||
f(ctx);
|
||||
let value_local = ctx.builder.set_new_local(); // TODO: Could get rid of this local by returning one from f
|
||||
|
||||
// TODO: Could get rid of this local by returning one from f
|
||||
let value_local = if bits == BitSize::QWORD {
|
||||
GenSafeReadWriteValue::I64(ctx.builder.set_new_local_i64())
|
||||
}
|
||||
else {
|
||||
GenSafeReadWriteValue::I32(ctx.builder.set_new_local())
|
||||
};
|
||||
|
||||
ctx.builder.get_local(&can_use_fast_path_local);
|
||||
|
||||
|
@ -901,7 +917,11 @@ pub fn gen_safe_read_write(
|
|||
ctx.builder.if_void();
|
||||
{
|
||||
ctx.builder.get_local(&address_local);
|
||||
ctx.builder.get_local(&value_local);
|
||||
|
||||
match &value_local {
|
||||
GenSafeReadWriteValue::I32(l) => ctx.builder.get_local(l),
|
||||
GenSafeReadWriteValue::I64(l) => ctx.builder.get_local_i64(l),
|
||||
}
|
||||
|
||||
ctx.builder
|
||||
.const_i32(ctx.start_of_current_instruction as i32);
|
||||
|
@ -916,7 +936,10 @@ pub fn gen_safe_read_write(
|
|||
BitSize::DWORD => {
|
||||
ctx.builder.call_fn3_ret("safe_write32_slow_jit");
|
||||
},
|
||||
BitSize::QWORD => dbg_assert!(false),
|
||||
BitSize::QWORD => {
|
||||
ctx.builder
|
||||
.call_fn3_i32_i64_i32_ret("safe_write64_slow_jit");
|
||||
},
|
||||
BitSize::DQWORD => dbg_assert!(false),
|
||||
}
|
||||
|
||||
|
@ -931,6 +954,7 @@ pub fn gen_safe_read_write(
|
|||
BitSize::BYTE => 8,
|
||||
BitSize::WORD => 16,
|
||||
BitSize::DWORD => 32,
|
||||
BitSize::QWORD => 64,
|
||||
_ => {
|
||||
dbg_assert!(false);
|
||||
0
|
||||
|
@ -948,7 +972,10 @@ pub fn gen_safe_read_write(
|
|||
ctx.builder.block_end();
|
||||
|
||||
ctx.builder.get_local(&phys_addr_local);
|
||||
ctx.builder.get_local(&value_local);
|
||||
match &value_local {
|
||||
GenSafeReadWriteValue::I32(l) => ctx.builder.get_local(l),
|
||||
GenSafeReadWriteValue::I64(l) => ctx.builder.get_local_i64(l),
|
||||
}
|
||||
|
||||
match bits {
|
||||
BitSize::BYTE => {
|
||||
|
@ -960,11 +987,16 @@ pub fn gen_safe_read_write(
|
|||
BitSize::DWORD => {
|
||||
ctx.builder.store_unaligned_i32(0);
|
||||
},
|
||||
BitSize::QWORD => dbg_assert!(false),
|
||||
BitSize::QWORD => {
|
||||
ctx.builder.store_unaligned_i64(0);
|
||||
},
|
||||
BitSize::DQWORD => dbg_assert!(false),
|
||||
}
|
||||
|
||||
ctx.builder.free_local(value_local);
|
||||
match value_local {
|
||||
GenSafeReadWriteValue::I32(l) => ctx.builder.free_local(l),
|
||||
GenSafeReadWriteValue::I64(l) => ctx.builder.free_local_i64(l),
|
||||
}
|
||||
ctx.builder.free_local(can_use_fast_path_local);
|
||||
ctx.builder.free_local(phys_addr_local);
|
||||
}
|
||||
|
|
|
@ -2859,6 +2859,10 @@ pub unsafe fn safe_read_write16_slow_jit(addr: i32, eip: i32) -> i32 {
|
|||
pub unsafe fn safe_read_write32s_slow_jit(addr: i32, eip: i32) -> i32 {
|
||||
safe_read_slow_jit(addr, 32, eip, true)
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe fn safe_read_write64_slow_jit(addr: i32, eip: i32) -> i32 {
|
||||
safe_read_slow_jit(addr, 64, eip, true)
|
||||
}
|
||||
|
||||
pub unsafe fn safe_write_slow_jit(
|
||||
addr: i32,
|
||||
|
|
|
@ -4,7 +4,7 @@ use codegen;
|
|||
use codegen::BitSize;
|
||||
use cpu::cpu::{
|
||||
FLAGS_ALL, FLAGS_DEFAULT, FLAGS_MASK, FLAG_ADJUST, FLAG_CARRY, FLAG_DIRECTION, FLAG_INTERRUPT,
|
||||
FLAG_OVERFLOW, FLAG_SUB, OPSIZE_8, OPSIZE_16, OPSIZE_32,
|
||||
FLAG_OVERFLOW, FLAG_SUB, FLAG_ZERO, OPSIZE_8, OPSIZE_16, OPSIZE_32,
|
||||
};
|
||||
use cpu::global_pointers;
|
||||
use jit::JitContext;
|
||||
|
@ -4226,6 +4226,56 @@ pub fn instr_0FC3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
|
|||
}
|
||||
pub fn instr_0FC3_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) { codegen::gen_trigger_ud(ctx) }
|
||||
|
||||
pub fn instr16_0FC7_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
|
||||
// cmpxchg8b
|
||||
codegen::gen_modrm_resolve(ctx, modrm_byte);
|
||||
let address_local = ctx.builder.set_new_local();
|
||||
codegen::gen_safe_read_write(ctx, BitSize::QWORD, &address_local, &|ref mut ctx| {
|
||||
let dest_operand = ctx.builder.tee_new_local_i64();
|
||||
codegen::gen_get_reg32(ctx, regs::EDX);
|
||||
ctx.builder.extend_unsigned_i32_to_i64();
|
||||
ctx.builder.const_i64(32);
|
||||
ctx.builder.shl_i64();
|
||||
codegen::gen_get_reg32(ctx, regs::EAX);
|
||||
ctx.builder.extend_unsigned_i32_to_i64();
|
||||
ctx.builder.or_i64();
|
||||
ctx.builder.eq_i64();
|
||||
ctx.builder.if_i64();
|
||||
{
|
||||
codegen::gen_set_flags_bits(ctx.builder, FLAG_ZERO);
|
||||
codegen::gen_get_reg32(ctx, regs::ECX);
|
||||
ctx.builder.extend_unsigned_i32_to_i64();
|
||||
ctx.builder.const_i64(32);
|
||||
ctx.builder.shl_i64();
|
||||
codegen::gen_get_reg32(ctx, regs::EBX);
|
||||
ctx.builder.extend_unsigned_i32_to_i64();
|
||||
ctx.builder.or_i64();
|
||||
}
|
||||
ctx.builder.else_();
|
||||
{
|
||||
codegen::gen_clear_flags_bits(ctx.builder, FLAG_ZERO);
|
||||
ctx.builder.get_local_i64(&dest_operand);
|
||||
ctx.builder.wrap_i64_to_i32();
|
||||
codegen::gen_set_reg32(ctx, regs::EAX);
|
||||
ctx.builder.get_local_i64(&dest_operand);
|
||||
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.get_local_i64(&dest_operand);
|
||||
}
|
||||
ctx.builder.block_end();
|
||||
codegen::gen_clear_flags_changed_bits(ctx.builder, FLAG_ZERO);
|
||||
ctx.builder.free_local_i64(dest_operand);
|
||||
});
|
||||
ctx.builder.free_local(address_local);
|
||||
}
|
||||
pub fn instr16_0FC7_1_reg_jit(ctx: &mut JitContext, _r: u32) { codegen::gen_trigger_ud(ctx); }
|
||||
pub fn instr32_0FC7_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
|
||||
instr16_0FC7_1_mem_jit(ctx, modrm_byte);
|
||||
}
|
||||
pub fn instr32_0FC7_1_reg_jit(ctx: &mut JitContext, _r: u32) { codegen::gen_trigger_ud(ctx); }
|
||||
|
||||
pub fn instr_C6_0_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
|
||||
// reg8[r] = imm;
|
||||
ctx.builder.const_i32(imm as i32);
|
||||
|
|
|
@ -717,6 +717,7 @@ impl WasmBuilder {
|
|||
pub fn shr_s_i32(&mut self) { self.instruction_body.push(op::OP_I32SHRS); }
|
||||
|
||||
pub fn eq_i32(&mut self) { self.instruction_body.push(op::OP_I32EQ); }
|
||||
pub fn eq_i64(&mut self) { self.instruction_body.push(op::OP_I64EQ); }
|
||||
pub fn ne_i32(&mut self) { self.instruction_body.push(op::OP_I32NE); }
|
||||
pub fn ne_i64(&mut self) { self.instruction_body.push(op::OP_I64NE); }
|
||||
pub fn le_i32(&mut self) { self.instruction_body.push(op::OP_I32LES); }
|
||||
|
|
Loading…
Reference in a new issue