Browse Source

Move imm reads into generate_jit

Fabian 3 years ago
parent
commit
159aaaa01f
2 changed files with 41 additions and 63 deletions
  1. 2 3
      gen/generate_jit.js
  2. 39 60
      src/rust/jit_instructions.rs

+ 2 - 3
gen/generate_jit.js

@@ -302,6 +302,7 @@ function gen_instruction_body_after_fixed_g(encoding, size)
 
             if(imm_read)
             {
+                mem_args.push("imm");
                 reg_args.push("imm");
             }
 
@@ -312,10 +313,8 @@ function gen_instruction_body_after_fixed_g(encoding, size)
                     if_blocks: [{
                         condition: "modrm_byte < 0xC0",
                         body: [].concat(
-                            // Note: Custom function is responsible for calling
-                            //       the proper read_imm function after calling
-                            //       gen_modrm_resolve
                             "let addr = ::modrm::decode(ctx.cpu, modrm_byte);",
+                            imm_read_bindings,
                             gen_call(`::jit_instructions::${instruction_name}_mem_jit`, mem_args),
                             mem_postfix
                         ),

+ 39 - 60
src/rust/jit_instructions.rs

@@ -221,10 +221,10 @@ macro_rules! define_instruction_read8(
     );
 
     ($fn:expr, $name_mem:ident, $name_reg:ident, $imm:ident) => (
-        pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
+        pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
             codegen::gen_modrm_resolve_safe_read8(ctx, modrm_byte);
             let dest_operand = ctx.builder.set_new_local();
-            let imm = make_imm_read!(ctx, $imm);
+            let imm = mask_imm!(imm, $imm);
             $fn(ctx.builder, &dest_operand, &LocalOrImmedate::Immediate(imm as i32));
             ctx.builder.free_local(dest_operand);
         }
@@ -260,10 +260,10 @@ macro_rules! define_instruction_read16(
     );
 
     ($fn:expr, $name_mem:ident, $name_reg:ident, $imm:ident) => (
-        pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
+        pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
             codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
             let dest_operand = ctx.builder.set_new_local();
-            let imm = make_imm_read!(ctx, $imm);
+            let imm = mask_imm!(imm, $imm);
             $fn(
                 ctx.builder,
                 &dest_operand,
@@ -305,10 +305,10 @@ macro_rules! define_instruction_read32(
     );
 
     ($fn:expr, $name_mem:ident, $name_reg:ident, $imm:ident) => (
-        pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
+        pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
             codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
             let dest_operand = ctx.builder.set_new_local();
-            let imm = make_imm_read!(ctx, $imm);
+            let imm = mask_imm!(imm, $imm);
             $fn(
                 ctx.builder,
                 &dest_operand,
@@ -394,14 +394,6 @@ macro_rules! mask_imm(
     ($imm:expr, imm32) => { $imm };
 );
 
-macro_rules! make_imm_read(
-    ($ctx:expr, imm8_5bits) => { $ctx.cpu.read_imm8() & 31 };
-    ($ctx:expr, imm8) => { $ctx.cpu.read_imm8() };
-    ($ctx:expr, imm8s) => { $ctx.cpu.read_imm8s() };
-    ($ctx:expr, imm16) => { $ctx.cpu.read_imm16() };
-    ($ctx:expr, imm32) => { $ctx.cpu.read_imm32() };
-);
-
 macro_rules! define_instruction_read_write_mem8(
     ($fn:expr, $name_mem:ident, $name_reg:ident, reg) => (
         pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
@@ -465,10 +457,10 @@ macro_rules! define_instruction_read_write_mem8(
     );
 
     ($fn:expr, $name_mem:ident, $name_reg:ident, $imm:ident) => (
-        pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
+        pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
             codegen::gen_modrm_resolve(ctx, modrm_byte);
             let address_local = ctx.builder.set_new_local();
-            let imm = make_imm_read!(ctx, $imm) as i32;
+            let imm = mask_imm!(imm, $imm) as i32;
             codegen::gen_safe_read_write(ctx, BitSize::BYTE, &address_local, &|ref mut ctx| {
                 ctx.builder.const_i32(imm as i32);
                 ctx.builder.call_fn2_ret($fn);
@@ -574,10 +566,10 @@ macro_rules! define_instruction_read_write_mem16(
     );
 
     ($fn:expr, $name_mem:ident, $name_reg:ident, reg, $imm:ident) => (
-        pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
+        pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm: u32) {
             codegen::gen_modrm_resolve(ctx, modrm_byte);
             let address_local = ctx.builder.set_new_local();
-            let imm = make_imm_read!(ctx, $imm) as i32;
+            let imm = mask_imm!(imm, $imm);
             codegen::gen_safe_read_write(ctx, BitSize::WORD, &address_local, &|ref mut ctx| {
                 codegen::gen_get_reg16(ctx, r);
                 ctx.builder.const_i32(imm as i32);
@@ -615,10 +607,10 @@ macro_rules! define_instruction_read_write_mem16(
     );
 
     ($fn:expr, $name_mem:ident, $name_reg:ident, $imm:ident) => (
-        pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
+        pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
             codegen::gen_modrm_resolve(ctx, modrm_byte);
             let address_local = ctx.builder.set_new_local();
-            let imm = make_imm_read!(ctx, $imm) as i32;
+            let imm = mask_imm!(imm, $imm) as i32;
             codegen::gen_safe_read_write(ctx, BitSize::WORD, &address_local, &|ref mut ctx| {
                 ctx.builder.const_i32(imm as i32);
                 ctx.builder.call_fn2_ret($fn);
@@ -731,10 +723,10 @@ macro_rules! define_instruction_read_write_mem32(
     );
 
     ($fn:expr, $name_mem:ident, $name_reg:ident, reg, $imm:ident) => (
-        pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
+        pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm: u32) {
             codegen::gen_modrm_resolve(ctx, modrm_byte);
             let address_local = ctx.builder.set_new_local();
-            let imm = make_imm_read!(ctx, $imm) as i32;
+            let imm = mask_imm!(imm, $imm) as i32;
             codegen::gen_safe_read_write(ctx, BitSize::DWORD, &address_local, &|ref mut ctx| {
                 codegen::gen_get_reg32(ctx, r);
                 ctx.builder.const_i32(imm as i32);
@@ -772,10 +764,10 @@ macro_rules! define_instruction_read_write_mem32(
     );
 
     ($fn:expr, $name_mem:ident, $name_reg:ident, ximm32) => (
-        pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
+        pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
             codegen::gen_modrm_resolve(ctx, modrm_byte);
             let address_local = ctx.builder.set_new_local();
-            let imm = make_imm_read!(ctx, imm32) as i32;
+            let imm = mask_imm!(imm, imm32) as i32;
             codegen::gen_safe_read_write(ctx, BitSize::DWORD, &address_local, &|ref mut ctx| {
                 let dest_operand = ctx.builder.set_new_local();
                 $fn(
@@ -800,10 +792,10 @@ macro_rules! define_instruction_read_write_mem32(
     );
 
     ($fn:expr, $name_mem:ident, $name_reg:ident, ximm8s) => (
-        pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
+        pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
             codegen::gen_modrm_resolve(ctx, modrm_byte);
             let address_local = ctx.builder.set_new_local();
-            let imm = make_imm_read!(ctx, imm8s) as i32;
+            let imm = mask_imm!(imm, imm8s) as i32;
             codegen::gen_safe_read_write(ctx, BitSize::DWORD, &address_local, &|ref mut ctx| {
                 let dest_operand = ctx.builder.set_new_local();
                 $fn(
@@ -828,10 +820,10 @@ macro_rules! define_instruction_read_write_mem32(
     );
 
     ($fn:expr, $name_mem:ident, $name_reg:ident, $imm:ident) => (
-        pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte) {
+        pub fn $name_mem(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
             codegen::gen_modrm_resolve(ctx, modrm_byte);
             let address_local = ctx.builder.set_new_local();
-            let imm = make_imm_read!(ctx, $imm) as i32;
+            let imm = mask_imm!(imm, $imm) as i32;
             codegen::gen_safe_read_write(ctx, BitSize::DWORD, &address_local, &|ref mut ctx| {
                 ctx.builder.const_i32(imm as i32);
                 ctx.builder.call_fn2_ret($fn);
@@ -1704,9 +1696,8 @@ pub fn instr32_68_jit(ctx: &mut JitContext, imm32: u32) { push32_imm_jit(ctx, im
 pub fn instr16_6A_jit(ctx: &mut JitContext, imm16: u32) { push16_imm_jit(ctx, imm16) }
 pub fn instr32_6A_jit(ctx: &mut JitContext, imm32: u32) { push32_imm_jit(ctx, imm32) }
 
-pub fn instr16_69_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
+pub fn instr16_69_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm16: u32) {
     codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
-    let imm16 = ctx.cpu.read_imm16();
     ctx.builder.const_i32(imm16 as i32);
     ctx.builder.call_fn2_ret("imul_reg16");
     codegen::gen_set_reg16(ctx, r);
@@ -1718,10 +1709,9 @@ pub fn instr16_69_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm16: u32) {
     codegen::gen_set_reg16(ctx, r2);
 }
 
-pub fn instr32_69_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
+pub fn instr32_69_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm32: u32) {
     codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
     let value_local = ctx.builder.set_new_local();
-    let imm32 = ctx.cpu.read_imm32();
     gen_imul3_reg32(
         ctx.builder,
         &ctx.register_locals[r as usize],
@@ -1739,9 +1729,8 @@ pub fn instr32_69_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm32: u32) {
     );
 }
 
-pub fn instr16_6B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
+pub fn instr16_6B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8s: u32) {
     codegen::gen_modrm_resolve_safe_read16(ctx, modrm_byte);
-    let imm8s = ctx.cpu.read_imm8s();
     ctx.builder.const_i32(imm8s as i32);
     ctx.builder.call_fn2_ret("imul_reg16");
     codegen::gen_set_reg16(ctx, r);
@@ -1753,10 +1742,9 @@ pub fn instr16_6B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8s: u32) {
     codegen::gen_set_reg16(ctx, r2);
 }
 
-pub fn instr32_6B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
+pub fn instr32_6B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8s: u32) {
     codegen::gen_modrm_resolve_safe_read32(ctx, modrm_byte);
     let value_local = ctx.builder.set_new_local();
-    let imm8s = ctx.cpu.read_imm8s();
     gen_imul3_reg32(
         ctx.builder,
         &ctx.register_locals[r as usize],
@@ -3179,20 +3167,20 @@ define_instruction_read32!(
     imm32
 );
 
-pub fn instr_F6_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
-    instr_F6_0_mem_jit(ctx, modrm_byte)
+pub fn instr_F6_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
+    instr_F6_0_mem_jit(ctx, modrm_byte, imm)
 }
 pub fn instr_F6_1_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
     instr_F6_0_reg_jit(ctx, r, imm)
 }
-pub fn instr16_F7_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
-    instr16_F7_0_mem_jit(ctx, modrm_byte)
+pub fn instr16_F7_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
+    instr16_F7_0_mem_jit(ctx, modrm_byte, imm)
 }
 pub fn instr16_F7_1_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
     instr16_F7_0_reg_jit(ctx, r, imm)
 }
-pub fn instr32_F7_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
-    instr32_F7_0_mem_jit(ctx, modrm_byte)
+pub fn instr32_F7_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
+    instr32_F7_0_mem_jit(ctx, modrm_byte, imm)
 }
 pub fn instr32_F7_1_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
     instr32_F7_0_reg_jit(ctx, r, imm)
@@ -4193,10 +4181,9 @@ pub fn instr_C6_0_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
     codegen::gen_set_reg8(ctx, r);
 }
 
-pub fn instr_C6_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
+pub fn instr_C6_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
     codegen::gen_modrm_resolve(ctx, modrm_byte);
     let address_local = ctx.builder.set_new_local();
-    let imm = ctx.cpu.read_imm8();
     ctx.builder.const_i32(imm as i32);
     let value_local = ctx.builder.set_new_local();
     codegen::gen_safe_write8(ctx, &address_local, &value_local);
@@ -4210,10 +4197,9 @@ pub fn instr16_C7_0_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
     codegen::gen_set_reg16(ctx, r);
 }
 
-pub fn instr16_C7_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
+pub fn instr16_C7_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
     codegen::gen_modrm_resolve(ctx, modrm_byte);
     let address_local = ctx.builder.set_new_local();
-    let imm = ctx.cpu.read_imm16();
     ctx.builder.const_i32(imm as i32);
     let value_local = ctx.builder.set_new_local();
     codegen::gen_safe_write16(ctx, &address_local, &value_local);
@@ -4227,10 +4213,9 @@ pub fn instr32_C7_0_reg_jit(ctx: &mut JitContext, r: u32, imm: u32) {
     codegen::gen_set_reg32(ctx, r);
 }
 
-pub fn instr32_C7_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
+pub fn instr32_C7_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm: u32) {
     codegen::gen_modrm_resolve(ctx, modrm_byte);
     let address_local = ctx.builder.set_new_local();
-    let imm = ctx.cpu.read_imm32();
     ctx.builder.const_i32(imm as i32);
     let value_local = ctx.builder.set_new_local();
     codegen::gen_safe_write32(ctx, &address_local, &value_local);
@@ -4478,10 +4463,9 @@ pub fn instr_F30F6F_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) {
     ctx.builder.call_fn2("instr_F30F6F_reg")
 }
 
-pub fn instr_660F70_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
+pub fn instr_660F70_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
     let dest = global_pointers::SSE_SCRATCH_REGISTER;
     codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
-    let imm8 = ctx.cpu.read_imm8();
     ctx.builder.const_i32(dest as i32);
     ctx.builder.const_i32(r as i32);
     ctx.builder.const_i32(imm8 as i32);
@@ -4494,10 +4478,9 @@ pub fn instr_660F70_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
     ctx.builder.const_i32(imm8 as i32);
     ctx.builder.call_fn3("instr_660F70");
 }
-pub fn instr_F20F70_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
+pub fn instr_F20F70_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
     let dest = global_pointers::SSE_SCRATCH_REGISTER;
     codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
-    let imm8 = ctx.cpu.read_imm8();
     ctx.builder.const_i32(dest as i32);
     ctx.builder.const_i32(r as i32);
     ctx.builder.const_i32(imm8 as i32);
@@ -4510,10 +4493,9 @@ pub fn instr_F20F70_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
     ctx.builder.const_i32(imm8 as i32);
     ctx.builder.call_fn3("instr_F20F70");
 }
-pub fn instr_F30F70_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) {
+pub fn instr_F30F70_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32, imm8: u32) {
     let dest = global_pointers::SSE_SCRATCH_REGISTER;
     codegen::gen_modrm_resolve_safe_read128(ctx, modrm_byte, dest);
-    let imm8 = ctx.cpu.read_imm8();
     ctx.builder.const_i32(dest as i32);
     ctx.builder.const_i32(r as i32);
     ctx.builder.const_i32(imm8 as i32);
@@ -4527,8 +4509,7 @@ pub fn instr_F30F70_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32, imm8: u32) {
     ctx.builder.call_fn3("instr_F30F70");
 }
 
-pub fn instr_0F73_2_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte) {
-    let _ = ctx.cpu.read_imm8();
+pub fn instr_0F73_2_mem_jit(ctx: &mut JitContext, _modrm_byte: ModrmByte, _imm: u32) {
     codegen::gen_trigger_ud(ctx);
 }
 pub fn instr_0F73_2_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
@@ -4709,9 +4690,8 @@ pub fn instr16_0FBA_4_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
         15,
     )
 }
-pub fn instr16_0FBA_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
+pub fn instr16_0FBA_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
     codegen::gen_modrm_resolve(ctx, modrm_byte);
-    let imm8 = ctx.cpu.read_imm8();
     ctx.builder.const_i32((imm8 as i32 & 15) >> 3);
     ctx.builder.add_i32();
     let address_local = ctx.builder.set_new_local();
@@ -4734,9 +4714,8 @@ pub fn instr32_0FBA_4_reg_jit(ctx: &mut JitContext, r: u32, imm8: u32) {
         31,
     )
 }
-pub fn instr32_0FBA_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
+pub fn instr32_0FBA_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, imm8: u32) {
     codegen::gen_modrm_resolve(ctx, modrm_byte);
-    let imm8 = ctx.cpu.read_imm8();
     ctx.builder.const_i32((imm8 as i32 & 31) >> 3);
     ctx.builder.add_i32();
     let address_local = ctx.builder.set_new_local();