Browse Source

jit: generate code for {66,}0f{c4,c5} (pinsrw, pextrw)

Fabian 1 year ago
parent
commit
de2a1439aa

+ 4 - 4
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 },

+ 0 - 12
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)

+ 2 - 7
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);

+ 53 - 0
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);

+ 5 - 5
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);