diff --git a/gen/x86_table.js b/gen/x86_table.js index 48635075..fdd12c51 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -819,10 +819,10 @@ const encodings = [ { opcode: 0x0FC3, e: 1, custom: 1, reg_ud: 1, }, // movnti: Uses normal registers, hence not marked as sse - { sse: 1, opcode: 0x0FC4, e: 1, imm8: 1 }, - { sse: 1, opcode: 0x660FC4, e: 1, imm8: 1 }, - { sse: 1, opcode: 0x0FC5, e: 1, mem_ud: 1, imm8: 1 }, - { sse: 1, opcode: 0x660FC5, e: 1, mem_ud: 1, imm8: 1, }, + { sse: 1, opcode: 0x0FC4, e: 1, imm8: 1, custom: 1 }, + { sse: 1, opcode: 0x660FC4, e: 1, imm8: 1, custom: 1 }, + { sse: 1, opcode: 0x0FC5, e: 1, mem_ud: 1, imm8: 1, custom: 1 }, + { sse: 1, opcode: 0x660FC5, e: 1, mem_ud: 1, imm8: 1, custom: 1 }, { sse: 1, opcode: 0x0FC6, e: 1, imm8: 1, custom: 1 }, { sse: 1, opcode: 0x660FC6, e: 1, imm8: 1, custom: 1 }, diff --git a/src/rust/codegen.rs b/src/rust/codegen.rs index 139669ee..fdd574a8 100644 --- a/src/rust/codegen.rs +++ b/src/rust/codegen.rs @@ -424,12 +424,6 @@ pub fn gen_fn2_const(builder: &mut WasmBuilder, name: &str, arg0: u32, arg1: u32 builder.const_i32(arg1 as i32); builder.call_fn2(name); } -pub fn gen_fn3_const(builder: &mut WasmBuilder, name: &str, arg0: u32, arg1: u32, arg2: u32) { - builder.const_i32(arg0 as i32); - builder.const_i32(arg1 as i32); - builder.const_i32(arg2 as i32); - builder.call_fn3(name); -} // helper functions for gen/generate_jit.js pub fn gen_modrm_fn0(builder: &mut WasmBuilder, name: &str) { @@ -441,12 +435,6 @@ pub fn gen_modrm_fn1(builder: &mut WasmBuilder, name: &str, arg0: u32) { builder.const_i32(arg0 as i32); builder.call_fn2(name); } -pub fn gen_modrm_fn2(builder: &mut WasmBuilder, name: &str, arg0: u32, arg1: u32) { - // generates: fn( _, arg0, arg1 ) - builder.const_i32(arg0 as i32); - builder.const_i32(arg1 as i32); - builder.call_fn3(name); -} pub fn gen_modrm_resolve(ctx: &mut JitContext, modrm_byte: ModrmByte) { modrm::gen(ctx, modrm_byte) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 9162f850..8bdd42a5 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -3723,6 +3723,8 @@ pub unsafe fn instr_0FC3_mem(addr: i32, r: i32) { // movnti return_on_pagefault!(safe_write32(addr, read_reg32(r))); } + +#[no_mangle] pub unsafe fn instr_0FC4(source: i32, r: i32, imm8: i32) { // pinsrw mm, r32/m16, imm8 let mut destination: [u16; 4] = std::mem::transmute(read_mmx64s(r)); @@ -3730,9 +3732,7 @@ pub unsafe fn instr_0FC4(source: i32, r: i32, imm8: i32) { write_mmx_reg64(r, std::mem::transmute(destination)); transition_fpu_to_mmx(); } -#[no_mangle] pub unsafe fn instr_0FC4_reg(r1: i32, r2: i32, imm: i32) { instr_0FC4(read_reg32(r1), r2, imm); } -#[no_mangle] pub unsafe fn instr_0FC4_mem(addr: i32, r: i32, imm: i32) { instr_0FC4(return_on_pagefault!(safe_read16(addr)), r, imm); } @@ -3743,15 +3743,12 @@ pub unsafe fn instr_660FC4(source: i32, r: i32, imm8: i32) { destination.u16[index as usize] = (source & 0xFFFF) as u16; write_xmm_reg128(r, destination); } -#[no_mangle] pub unsafe fn instr_660FC4_reg(r1: i32, r2: i32, imm: i32) { instr_660FC4(read_reg32(r1), r2, imm); } -#[no_mangle] pub unsafe fn instr_660FC4_mem(addr: i32, r: i32, imm: i32) { instr_660FC4(return_on_pagefault!(safe_read16(addr)), r, imm); } -#[no_mangle] pub unsafe fn instr_0FC5_mem(_addr: i32, _r: i32, _imm8: i32) { trigger_ud(); } #[no_mangle] pub unsafe fn instr_0FC5_reg(r1: i32, r2: i32, imm8: i32) { @@ -3760,9 +3757,7 @@ pub unsafe fn instr_0FC5_reg(r1: i32, r2: i32, imm8: i32) { write_reg32(r2, data[(imm8 & 3) as usize] as i32); transition_fpu_to_mmx(); } -#[no_mangle] pub unsafe fn instr_660FC5_mem(_addr: i32, _r: i32, _imm8: i32) { trigger_ud(); } -#[no_mangle] pub unsafe fn instr_660FC5_reg(r1: i32, r2: i32, imm8: i32) { // pextrw r32, xmm, imm8 let data = read_xmm128s(r1); diff --git a/src/rust/jit_instructions.rs b/src/rust/jit_instructions.rs index 225e8783..4a374669 100644 --- a/src/rust/jit_instructions.rs +++ b/src/rust/jit_instructions.rs @@ -5338,6 +5338,59 @@ 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 instr_0FC4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) { + codegen::gen_modrm_resolve(ctx, modrm_byte); + let address_local = ctx.builder.set_new_local(); + codegen::gen_safe_read16(ctx, &address_local); + ctx.builder.const_i32(r as i32); + ctx.builder.const_i32(imm8 as i32); + ctx.builder.call_fn3("instr_0FC4"); + ctx.builder.free_local(address_local); +} +pub fn instr_0FC4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) { + codegen::gen_get_reg32(ctx, r1); + ctx.builder.const_i32(r2 as i32); + ctx.builder.const_i32(imm8 as i32); + ctx.builder.call_fn3("instr_0FC4"); +} + +pub fn instr_660FC4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) { + ctx.builder.const_i32(0); + codegen::gen_modrm_resolve(ctx, modrm_byte); + let address_local = ctx.builder.set_new_local(); + codegen::gen_safe_read16(ctx, &address_local); + ctx.builder + .store_aligned_u16(global_pointers::get_reg_xmm_offset(r) + ((imm8 & 7) << 1)); + ctx.builder.free_local(address_local); +} +pub fn instr_660FC4_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) { + ctx.builder.const_i32(0); + codegen::gen_get_reg32(ctx, r1); + ctx.builder + .store_aligned_u16(global_pointers::get_reg_xmm_offset(r2) + ((imm8 & 7) << 1)); +} + +pub fn instr_0FC5_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _r: u32, _imm8: u32) { + codegen::gen_trigger_ud(ctx) +} +pub fn instr_0FC5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) { + codegen::gen_move_registers_from_locals_to_memory(ctx); + ctx.builder.const_i32(r1 as i32); + ctx.builder.const_i32(r2 as i32); + ctx.builder.const_i32(imm8 as i32); + ctx.builder.call_fn3("instr_0FC5_reg"); + codegen::gen_move_registers_from_memory_to_locals(ctx); +} + +pub fn instr_660FC5_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _r: u32, _imm8: u32) { + codegen::gen_trigger_ud(ctx) +} +pub fn instr_660FC5_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) { + ctx.builder + .load_fixed_u16(global_pointers::get_reg_xmm_offset(r1) + ((imm8 & 7) << 1)); + codegen::gen_set_reg32(ctx, r2); +} + pub fn instr16_0FC7_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { // cmpxchg8b codegen::gen_modrm_resolve(ctx, modrm_byte); diff --git a/src/rust/wasmgen/wasm_builder.rs b/src/rust/wasmgen/wasm_builder.rs index 2abcd97b..50e002d6 100644 --- a/src/rust/wasmgen/wasm_builder.rs +++ b/src/rust/wasmgen/wasm_builder.rs @@ -725,11 +725,11 @@ impl WasmBuilder { write_leb_u32(&mut self.instruction_body, byte_offset); } - //pub fn store_aligned_u16(&mut self, byte_offset: u32) { - // self.instruction_body.push(op::OP_I32STORE16); - // self.instruction_body.push(op::MEM_ALIGN16); - // write_leb_u32(&mut self.instruction_body, byte_offset); - //} + pub fn store_aligned_u16(&mut self, byte_offset: u32) { + self.instruction_body.push(op::OP_I32STORE16); + self.instruction_body.push(op::MEM_ALIGN16); + write_leb_u32(&mut self.instruction_body, byte_offset); + } pub fn store_aligned_i32(&mut self, byte_offset: u32) { self.instruction_body.push(op::OP_I32STORE);