From fd5842ef64713ee301fa810fd0f01b9e83263910 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 1 Sep 2023 15:12:20 +0200 Subject: [PATCH 001/180] Update x86_table.js --- gen/x86_table.js | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/gen/x86_table.js b/gen/x86_table.js index 840c6ee1fd..8afa267cc2 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -306,7 +306,7 @@ const encodings = [ { opcode: 0xDA, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDB, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDB, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, skip_mem: 1, }, // unimplemented: fisttp (sse3) + { opcode: 0xDB, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, skip_mem: 1, }, // fisttp (sse3) { opcode: 0xDB, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDB, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDB, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, }, @@ -324,7 +324,7 @@ const encodings = [ { opcode: 0xDC, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDD, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, - { opcode: 0xDD, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, skip_mem: 1, }, // unimplemented: fisttp (sse3) + { opcode: 0xDD, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, // fisttp (sse3) { opcode: 0xDD, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, { opcode: 0xDD, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, { opcode: 0xDD, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, skip_mem: 1 }, // frstor @@ -341,14 +341,14 @@ const encodings = [ { opcode: 0xDE, e: 1, fixed_g: 6, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDE, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDF, e: 1, fixed_g: 0, custom: 0, is_fpu: 1, task_switch_test: 1 }, - { opcode: 0xDF, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, skip_mem: 1 }, // unimplemented: fisttp (sse3) - { opcode: 0xDF, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1 }, - { opcode: 0xDF, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1 }, + { opcode: 0xDF, e: 1, fixed_g: 0, custom: 0, is_fpu: 1, task_switch_test: 1, }, + { opcode: 0xDF, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) + { opcode: 0xDF, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, }, + { opcode: 0xDF, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, skip_mem: 1 }, // unimplemented: Binary Coded Decimals - { opcode: 0xDF, e: 1, fixed_g: 5, custom: 1, is_fpu: 1, task_switch_test: 1 }, - { opcode: 0xDF, e: 1, fixed_g: 6, custom: 1, is_fpu: 1, task_switch_test: 1 }, - { opcode: 0xDF, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1 }, + { opcode: 0xDF, e: 1, fixed_g: 5, custom: 1, is_fpu: 1, task_switch_test: 1, }, + { opcode: 0xDF, e: 1, fixed_g: 6, custom: 1, is_fpu: 1, task_switch_test: 1, }, + { opcode: 0xDF, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, // loop, jcxz, etc. { opcode: 0xE0, os: 1, imm8s: 1, no_block_boundary_in_interpreted: 1, skip: 1, block_boundary: 1, jump_offset_imm: 1, custom: 1, conditional_jump: 1, }, @@ -621,15 +621,19 @@ const encodings = [ { sse: 1, opcode: 0x0F10, e: 1, custom: 1 }, { sse: 1, opcode: 0xF30F10, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F10, e: 1, custom: 1 }, + { sse: 1, opcode: 0x660F7C, e: 1, custom: 1 }, // sse3 + { sse: 1, opcode: 0x660F7D, e: 1, custom: 1 }, // sse3 { sse: 1, opcode: 0xF20F10, e: 1, custom: 1 }, + { sse: 1, opcode: 0xF20F7C, e: 1, custom: 1 }, // sse3 + { sse: 1, opcode: 0xF20F7D, e: 1, custom: 1 }, // sse3 { sse: 1, opcode: 0x0F11, e: 1, custom: 1 }, { sse: 1, opcode: 0xF30F11, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F11, e: 1, custom: 1 }, { sse: 1, opcode: 0xF20F11, e: 1, custom: 1 }, { sse: 1, opcode: 0x0F12, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F12, reg_ud: 1, e: 1, custom: 1 }, - { sse: 1, opcode: 0xF20F12, e: 1, skip: 1, block_boundary: 1, }, // sse3 - { sse: 1, opcode: 0xF30F12, e: 1, skip: 1, block_boundary: 1, }, // sse3 + { sse: 1, opcode: 0xF20F12, e: 1, block_boundary: 1, }, // sse3 + { sse: 1, opcode: 0xF30F12, e: 1, block_boundary: 1, }, // sse3 { sse: 1, opcode: 0x0F13, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F13, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0x0F14, e: 1, custom: 1 }, @@ -638,7 +642,7 @@ const encodings = [ { sse: 1, opcode: 0x660F15, e: 1, custom: 1 }, { sse: 1, opcode: 0x0F16, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F16, reg_ud: 1, e: 1, custom: 1 }, - { sse: 1, opcode: 0xF30F16, skip: 1, e: 1, block_boundary: 1, }, // sse3 + { sse: 1, opcode: 0xF30F16, e: 1, block_boundary: 1, }, // sse3 { sse: 1, opcode: 0x0F17, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F17, reg_ud: 1, e: 1, custom: 1 }, From da44d545aee73faa066fc70df74db19f8ec3ef02 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 1 Sep 2023 15:25:51 +0200 Subject: [PATCH 002/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 91 ++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index efa1bbba2e..115d5eca21 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1822,6 +1822,42 @@ pub unsafe fn instr_F30F59_mem(addr: i32, r: i32) { instr_F30F59(return_on_pagefault!(safe_read_f32(addr)), r); } #[no_mangle] +pub unsafe fn instr_660F7C(source: reg128, r: i32) { + // haddps xmm, xmm/mem128 + let destination = read_xmm128s(r); + let result = reg128 { + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], + ], + }; + write_xmm_reg128(r, result); +} +pub unsafe fn instr_660F7C_reg(r1: i32, r2: i32) { instr_660F7C(read_xmm128s(r1), r2); } +pub unsafe fn instr_660F7C_mem(addr: i32, r: i32) { + instr_660F7C(return_on_pagefault!(safe_read128s(addr)), r); +} +#[no_mangle] +pub unsafe fn instr_660F7D(source: reg128, r: i32) { + // haddps xmm, xmm/mem128 + let destination = read_xmm128s(r); + let result = reg128 { + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], + ], + }; + write_xmm_reg128(r, result); +} +pub unsafe fn instr_660F7D_reg(r1: i32, r2: i32) { instr_660F7D(read_xmm128s(r1), r2); } +pub unsafe fn instr_660F7D_mem(addr: i32, r: i32) { + instr_660F7D(return_on_pagefault!(safe_read128s(addr)), r); +} +#[no_mangle] pub unsafe fn instr_F20F7C(source: reg128, r: i32) { // haddps xmm, xmm/mem128 let destination = read_xmm128s(r); @@ -1839,7 +1875,60 @@ pub unsafe fn instr_F20F7C_reg(r1: i32, r2: i32) { instr_F20F7C(read_xmm128s(r1) pub unsafe fn instr_F20F7C_mem(addr: i32, r: i32) { instr_F20F7C(return_on_pagefault!(safe_read128s(addr)), r); } - +#[no_mangle] +pub unsafe fn instr_DF(source: reg128, r: i32) { + // haddps xmm, xmm/mem128 + let destination = read_xmm128s(r); + let result = reg128 { + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], + ], + }; + write_xmm_reg128(r, result); +} +pub unsafe fn instr_DF_reg(r1: i32, r2: i32) { instr_DF(read_xmm128s(r1), r2); } +pub unsafe fn instr_DF_mem(addr: i32, r: i32) { + instr_DF(return_on_pagefault!(safe_read128s(addr)), r); +} +#[no_mangle] +pub unsafe fn instr_DD(source: reg128, r: i32) { + // haddps xmm, xmm/mem128 + let destination = read_xmm128s(r); + let result = reg128 { + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], + ], + }; + write_xmm_reg128(r, result); +} +pub unsafe fn instr_DD_reg(r1: i32, r2: i32) { instr_DD(read_xmm128s(r1), r2); } +pub unsafe fn instr_DD_mem(addr: i32, r: i32) { + instr_DD(return_on_pagefault!(safe_read128s(addr)), r); +} +#[no_mangle] +pub unsafe fn instr_F20F7D(source: reg128, r: i32) { + // haddps xmm, xmm/mem128 + let destination = read_xmm128s(r); + let result = reg128 { + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], + ], + }; + write_xmm_reg128(r, result); +} +pub unsafe fn instr_F20F7D_reg(r1: i32, r2: i32) { instr_F20F7D(read_xmm128s(r1), r2); } +pub unsafe fn instr_F20F7D_mem(addr: i32, r: i32) { + instr_F20F7D(return_on_pagefault!(safe_read128s(addr)), r); +} #[no_mangle] pub unsafe fn instr_0F5A(source: u64, r: i32) { // cvtps2pd xmm1, xmm2/m64 From e6663a151737f7e5fd4ed7dcdf62c25f7fd88bea Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 1 Sep 2023 15:28:29 +0200 Subject: [PATCH 003/180] Update jit_instructions.rs --- src/rust/jit_instructions.rs | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/rust/jit_instructions.rs b/src/rust/jit_instructions.rs index f8c6a05c66..66c0ac9120 100644 --- a/src/rust/jit_instructions.rs +++ b/src/rust/jit_instructions.rs @@ -6134,7 +6134,12 @@ pub fn instr_F20F7C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) pub fn instr_F20F7C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_read128_xmm_xmm(ctx, "instr_F20F7C", r1, r2); } - +pub fn instr_F20F7D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { + sse_read128_xmm_mem(ctx, "instr_F20F7D", modrm_byte, r); +} +pub fn instr_F20F7D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { + sse_read128_xmm_xmm(ctx, "instr_F20F7D", r1, r2); +} pub fn instr_0F5A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { sse_read64_xmm_mem(ctx, "instr_0F5A", modrm_byte, r); } @@ -6172,6 +6177,30 @@ pub fn instr_660F5B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) pub fn instr_660F5B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_read128_xmm_xmm(ctx, "instr_660F5B", r1, r2); } +pub fn instr_660F7D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { + sse_read128_xmm_mem(ctx, "instr_660F7D", modrm_byte, r); +} +pub fn instr_660F7D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { + sse_read128_xmm_xmm(ctx, "instr_660F7D", r1, r2); +} +pub fn instr_660F7C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { + sse_read128_xmm_mem(ctx, "instr_660F7C", modrm_byte, r); +} +pub fn instr_660F7C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { + sse_read128_xmm_xmm(ctx, "instr_660F7C", r1, r2); +} +pub fn instr_DF_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { + sse_read128_xmm_mem(ctx, "instr_DF", modrm_byte, r); +} +pub fn instr_DF_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { + sse_read128_xmm_xmm(ctx, "instr_DF", r1, r2); +} +pub fn instr_DD_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { + sse_read128_xmm_mem(ctx, "instr_DD", modrm_byte, r); +} +pub fn instr_DD_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { + sse_read128_xmm_xmm(ctx, "instr_DD", r1, r2); +} pub fn instr_F30F5B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { sse_read128_xmm_mem(ctx, "instr_F30F5B", modrm_byte, r); } From aeba09af1d92a34aaf6d63fdf2fafa7b510835d7 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 1 Sep 2023 15:51:28 +0200 Subject: [PATCH 004/180] Update jit_instructions.rs --- src/rust/jit_instructions.rs | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/rust/jit_instructions.rs b/src/rust/jit_instructions.rs index 66c0ac9120..2ce637f67f 100644 --- a/src/rust/jit_instructions.rs +++ b/src/rust/jit_instructions.rs @@ -5674,6 +5674,16 @@ pub fn instr_F20F10_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { ctx.builder .store_aligned_i64(global_pointers::get_reg_xmm_offset(r2)); } +pub fn instr_F20F12_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { + instr_F30F7E_mem_jit(ctx, modrm_byte, r) +} +pub fn instr_F20F12_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { + ctx.builder.const_i32(0); + ctx.builder + .load_fixed_i64(global_pointers::get_reg_xmm_offset(r1)); + ctx.builder + .store_aligned_i64(global_pointers::get_reg_xmm_offset(r2)); +} pub fn instr_F30F10_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { instr_660F6E_mem_jit(ctx, modrm_byte, r) } @@ -5684,7 +5694,26 @@ pub fn instr_F30F10_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { ctx.builder .store_aligned_i32(global_pointers::get_reg_xmm_offset(r2)); } - +pub fn instr_F30F12_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { + instr_660F6E_mem_jit(ctx, modrm_byte, r) +} +pub fn instr_F30F12_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { + ctx.builder.const_i32(0); + ctx.builder + .load_fixed_i32(global_pointers::get_reg_xmm_offset(r1)); + ctx.builder + .store_aligned_i32(global_pointers::get_reg_xmm_offset(r2)); +} +pub fn instr_F30F16_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { + instr_660F6E_mem_jit(ctx, modrm_byte, r) +} +pub fn instr_F30F16_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { + ctx.builder.const_i32(0); + ctx.builder + .load_fixed_i32(global_pointers::get_reg_xmm_offset(r1)); + ctx.builder + .store_aligned_i32(global_pointers::get_reg_xmm_offset(r2)); +} pub fn instr_0F11_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { instr_0F29_mem_jit(ctx, modrm_byte, r) } From fc9631f9c61494cfa5f0e71ba862b768c734192f Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 1 Sep 2023 16:18:55 +0200 Subject: [PATCH 005/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 115d5eca21..65fcc3df1c 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -3234,7 +3234,7 @@ pub unsafe fn instr_0FA2() { // pentium eax = 3 | 6 << 4 | 15 << 8; ebx = 1 << 16 | 8 << 8; // cpu count, clflush size - ecx = 1 << 23 | 1 << 30; // popcnt, rdrand + ecx = 1 << 0 | 1 << 23 | 1 << 30; // popcnt, rdrand, sse3 let vme = 0 << 1; if ::config::VMWARE_HYPERVISOR_PORT { ecx |= 1 << 31 From f51f23017711b8ece1034bd14c5f3e2f28c77fe2 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 1 Sep 2023 16:48:12 +0200 Subject: [PATCH 006/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 65fcc3df1c..82107e4bdb 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -3234,7 +3234,7 @@ pub unsafe fn instr_0FA2() { // pentium eax = 3 | 6 << 4 | 15 << 8; ebx = 1 << 16 | 8 << 8; // cpu count, clflush size - ecx = 1 << 0 | 1 << 23 | 1 << 30; // popcnt, rdrand, sse3 + ecx = 1 << 23 | 1 << 30 | 1 << 0; // popcnt, rdrand, sse3 let vme = 0 << 1; if ::config::VMWARE_HYPERVISOR_PORT { ecx |= 1 << 31 From b789f9a4e26fac80035eabbf89a2f7e1817714b2 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sat, 2 Sep 2023 07:57:38 +0200 Subject: [PATCH 007/180] Update x86_table.js --- gen/x86_table.js | 1 - 1 file changed, 1 deletion(-) diff --git a/gen/x86_table.js b/gen/x86_table.js index 8afa267cc2..0f1b4edc1b 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -624,7 +624,6 @@ const encodings = [ { sse: 1, opcode: 0x660F7C, e: 1, custom: 1 }, // sse3 { sse: 1, opcode: 0x660F7D, e: 1, custom: 1 }, // sse3 { sse: 1, opcode: 0xF20F10, e: 1, custom: 1 }, - { sse: 1, opcode: 0xF20F7C, e: 1, custom: 1 }, // sse3 { sse: 1, opcode: 0xF20F7D, e: 1, custom: 1 }, // sse3 { sse: 1, opcode: 0x0F11, e: 1, custom: 1 }, { sse: 1, opcode: 0xF30F11, e: 1, custom: 1 }, From 023798fc59743dec206b6398f44e163fcc735da8 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sat, 2 Sep 2023 08:17:11 +0200 Subject: [PATCH 008/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 72 +++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 16 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 82107e4bdb..56f3768ad5 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -554,14 +554,41 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { write_xmm64(r, data); } #[no_mangle] -pub unsafe fn instr_F20F12_mem(_addr: i32, _r: i32) { unimplemented_sse(); } -#[no_mangle] -pub unsafe fn instr_F20F12_reg(_r1: i32, _r2: i32) { unimplemented_sse(); } -#[no_mangle] -pub unsafe fn instr_F30F12_mem(_addr: i32, _r: i32) { unimplemented_sse(); } +pub unsafe fn instr_F20F12(source: reg128, r: i32) { + // movddup xmm, xmm/mem128 + let destination = read_xmm128s(r); + let result = reg128 { + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], + ], + }; + write_xmm_reg128(r, result); +} +pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm128s(r1), r2); } +pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { + instr_F20F12(return_on_pagefault!(safe_read128s(addr)), r); +} #[no_mangle] -pub unsafe fn instr_F30F12_reg(_r1: i32, _r2: i32) { unimplemented_sse(); } - +pub unsafe fn instr_F30F12(source: reg128, r: i32) { + // movsldup xmm, xmm/mem128 + let destination = read_xmm128s(r); + let result = reg128 { + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], + ], + }; + write_xmm_reg128(r, result); +} +pub unsafe fn instr_FF30F12_reg(r1: i32, r2: i32) { instr_F30F12(read_xmm128s(r1), r2); } +pub unsafe fn instr_F30F12_mem(addr: i32, r: i32) { + instr_F30F12(return_on_pagefault!(safe_read128s(addr)), r); +} pub unsafe fn instr_0F13_mem(addr: i32, r: i32) { // movlps m64, xmm movl_r128_m64(addr, r); @@ -658,10 +685,23 @@ pub unsafe fn instr_660F16_mem(addr: i32, r: i32) { } pub unsafe fn instr_660F16_reg(_r1: i32, _r2: i32) { trigger_ud(); } #[no_mangle] -pub unsafe fn instr_F30F16_reg(_r1: i32, _r2: i32) { unimplemented_sse(); } -#[no_mangle] -pub unsafe fn instr_F30F16_mem(_addr: i32, _r: i32) { unimplemented_sse(); } - +pub unsafe fn instr_F30F16(source: reg128, r: i32) { + // movshdup xmm, xmm/mem128 + let destination = read_xmm128s(r); + let result = reg128 { + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], + ], + }; + write_xmm_reg128(r, result); +} +pub unsafe fn instr_F30F16_reg(r1: i32, r2: i32) { instr_F30F16(read_xmm128s(r1), r2); } +pub unsafe fn instr_F30F16_mem(addr: i32, r: i32) { + instr_F30F16(return_on_pagefault!(safe_read128s(addr)), r); +} pub unsafe fn instr_0F17_mem(addr: i32, r: i32) { // movhps m64, xmm movh_r128_m64(addr, r); @@ -1823,7 +1863,7 @@ pub unsafe fn instr_F30F59_mem(addr: i32, r: i32) { } #[no_mangle] pub unsafe fn instr_660F7C(source: reg128, r: i32) { - // haddps xmm, xmm/mem128 + // haddpd xmm, xmm/mem128 let destination = read_xmm128s(r); let result = reg128 { f32: [ @@ -1841,7 +1881,7 @@ pub unsafe fn instr_660F7C_mem(addr: i32, r: i32) { } #[no_mangle] pub unsafe fn instr_660F7D(source: reg128, r: i32) { - // haddps xmm, xmm/mem128 + // hsupbd xmm, xmm/mem128 let destination = read_xmm128s(r); let result = reg128 { f32: [ @@ -1877,7 +1917,7 @@ pub unsafe fn instr_F20F7C_mem(addr: i32, r: i32) { } #[no_mangle] pub unsafe fn instr_DF(source: reg128, r: i32) { - // haddps xmm, xmm/mem128 + // fisttp xmm, xmm/mem128 let destination = read_xmm128s(r); let result = reg128 { f32: [ @@ -1895,7 +1935,7 @@ pub unsafe fn instr_DF_mem(addr: i32, r: i32) { } #[no_mangle] pub unsafe fn instr_DD(source: reg128, r: i32) { - // haddps xmm, xmm/mem128 + // fisttp xmm, xmm/mem128 let destination = read_xmm128s(r); let result = reg128 { f32: [ @@ -1913,7 +1953,7 @@ pub unsafe fn instr_DD_mem(addr: i32, r: i32) { } #[no_mangle] pub unsafe fn instr_F20F7D(source: reg128, r: i32) { - // haddps xmm, xmm/mem128 + // hsubps xmm, xmm/mem128 let destination = read_xmm128s(r); let result = reg128 { f32: [ From c4237fbeb8a35c85ae735aecbac593e70ae841fd Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sat, 2 Sep 2023 08:20:07 +0200 Subject: [PATCH 009/180] Update instructions_0f.rs heh, was just a little typo then lol --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 56f3768ad5..59d92dde04 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -585,7 +585,7 @@ pub unsafe fn instr_F30F12(source: reg128, r: i32) { }; write_xmm_reg128(r, result); } -pub unsafe fn instr_FF30F12_reg(r1: i32, r2: i32) { instr_F30F12(read_xmm128s(r1), r2); } +pub unsafe fn instr_F30F12_reg(r1: i32, r2: i32) { instr_F30F12(read_xmm128s(r1), r2); } pub unsafe fn instr_F30F12_mem(addr: i32, r: i32) { instr_F30F12(return_on_pagefault!(safe_read128s(addr)), r); } From 2ec1fb03b45b1079d109d5c328bfb64b8ec8dc08 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sat, 2 Sep 2023 09:29:43 +0200 Subject: [PATCH 010/180] Update x86_table.js --- gen/x86_table.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gen/x86_table.js b/gen/x86_table.js index 0f1b4edc1b..6c876242f1 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -327,9 +327,9 @@ const encodings = [ { opcode: 0xDD, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, // fisttp (sse3) { opcode: 0xDD, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, { opcode: 0xDD, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, - { opcode: 0xDD, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, skip_mem: 1 }, // frstor + { opcode: 0xDD, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, // frstor { opcode: 0xDD, e: 1, fixed_g: 5, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, - { opcode: 0xDD, e: 1, fixed_g: 6, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, skip_mem: 1 }, // fsave + { opcode: 0xDD, e: 1, fixed_g: 6, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, // fsave { opcode: 0xDD, e: 1, fixed_g: 7, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, { opcode: 0xDE, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, }, @@ -345,7 +345,7 @@ const encodings = [ { opcode: 0xDF, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) { opcode: 0xDF, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDF, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, skip_mem: 1 }, // unimplemented: Binary Coded Decimals + { opcode: 0xDF, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, }, // unimplemented: Binary Coded Decimals { opcode: 0xDF, e: 1, fixed_g: 5, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 6, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, From 25525d7f2fb74d91576a1f7d79dfa39c6b1217a4 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sat, 2 Sep 2023 13:33:40 +0200 Subject: [PATCH 011/180] Update x86_table.js --- gen/x86_table.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen/x86_table.js b/gen/x86_table.js index 6c876242f1..1449813099 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -306,7 +306,7 @@ const encodings = [ { opcode: 0xDA, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDB, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDB, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, skip_mem: 1, }, // fisttp (sse3) + { opcode: 0xDB, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) { opcode: 0xDB, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDB, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDB, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, }, From a8911db1b8710e9792ec1358531539be1ebbe4e5 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sat, 2 Sep 2023 19:24:58 +0200 Subject: [PATCH 012/180] Update x86_table.js --- gen/x86_table.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gen/x86_table.js b/gen/x86_table.js index 1449813099..aeb0f85b01 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -306,7 +306,7 @@ const encodings = [ { opcode: 0xDA, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDB, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDB, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) + { opcode: 0xDB, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) { opcode: 0xDB, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDB, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDB, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, }, @@ -324,7 +324,7 @@ const encodings = [ { opcode: 0xDC, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDD, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, - { opcode: 0xDD, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, // fisttp (sse3) + { opcode: 0xDD, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, // fisttp (sse3) { opcode: 0xDD, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, { opcode: 0xDD, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, { opcode: 0xDD, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, // frstor @@ -342,7 +342,7 @@ const encodings = [ { opcode: 0xDE, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 0, custom: 0, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDF, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) + { opcode: 0xDF, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) { opcode: 0xDF, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, }, // unimplemented: Binary Coded Decimals @@ -631,8 +631,8 @@ const encodings = [ { sse: 1, opcode: 0xF20F11, e: 1, custom: 1 }, { sse: 1, opcode: 0x0F12, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F12, reg_ud: 1, e: 1, custom: 1 }, - { sse: 1, opcode: 0xF20F12, e: 1, block_boundary: 1, }, // sse3 - { sse: 1, opcode: 0xF30F12, e: 1, block_boundary: 1, }, // sse3 + { sse: 1, opcode: 0xF20F12, e: 1, block_boundary: 1, custom: 1 }, // sse3 + { sse: 1, opcode: 0xF30F12, e: 1, block_boundary: 1, custom: 1 }, // sse3 { sse: 1, opcode: 0x0F13, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F13, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0x0F14, e: 1, custom: 1 }, From 883b4d47fdb4b40104c77be863b638a9c45cfc20 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sat, 2 Sep 2023 19:29:20 +0200 Subject: [PATCH 013/180] Update x86_table.js --- gen/x86_table.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gen/x86_table.js b/gen/x86_table.js index aeb0f85b01..18794f8db8 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -306,7 +306,7 @@ const encodings = [ { opcode: 0xDA, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDB, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDB, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) + { opcode: 0xDB, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) { opcode: 0xDB, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDB, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDB, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, }, @@ -324,7 +324,7 @@ const encodings = [ { opcode: 0xDC, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDD, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, - { opcode: 0xDD, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, // fisttp (sse3) + { opcode: 0xDD, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, // fisttp (sse3) { opcode: 0xDD, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, { opcode: 0xDD, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, { opcode: 0xDD, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, // frstor @@ -342,7 +342,7 @@ const encodings = [ { opcode: 0xDE, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 0, custom: 0, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDF, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) + { opcode: 0xDF, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) { opcode: 0xDF, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, }, // unimplemented: Binary Coded Decimals @@ -631,8 +631,8 @@ const encodings = [ { sse: 1, opcode: 0xF20F11, e: 1, custom: 1 }, { sse: 1, opcode: 0x0F12, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F12, reg_ud: 1, e: 1, custom: 1 }, - { sse: 1, opcode: 0xF20F12, e: 1, block_boundary: 1, custom: 1 }, // sse3 - { sse: 1, opcode: 0xF30F12, e: 1, block_boundary: 1, custom: 1 }, // sse3 + { sse: 1, opcode: 0xF20F12, e: 1, block_boundary: 1, custom: 0 }, // sse3 + { sse: 1, opcode: 0xF30F12, e: 1, block_boundary: 1, custom: 0 }, // sse3 { sse: 1, opcode: 0x0F13, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F13, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0x0F14, e: 1, custom: 1 }, From c15cc35ffd826c80c1d8a1002ad180454dc82688 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sat, 2 Sep 2023 19:34:43 +0200 Subject: [PATCH 014/180] Update x86_table.js --- gen/x86_table.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gen/x86_table.js b/gen/x86_table.js index 18794f8db8..6c47a43cd8 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -324,7 +324,7 @@ const encodings = [ { opcode: 0xDC, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDD, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, - { opcode: 0xDD, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, // fisttp (sse3) + { opcode: 0xDD, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, // fisttp (sse3) { opcode: 0xDD, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, { opcode: 0xDD, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, { opcode: 0xDD, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, // frstor @@ -342,7 +342,7 @@ const encodings = [ { opcode: 0xDE, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 0, custom: 0, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDF, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) + { opcode: 0xDF, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) { opcode: 0xDF, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, }, // unimplemented: Binary Coded Decimals @@ -631,8 +631,8 @@ const encodings = [ { sse: 1, opcode: 0xF20F11, e: 1, custom: 1 }, { sse: 1, opcode: 0x0F12, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F12, reg_ud: 1, e: 1, custom: 1 }, - { sse: 1, opcode: 0xF20F12, e: 1, block_boundary: 1, custom: 0 }, // sse3 - { sse: 1, opcode: 0xF30F12, e: 1, block_boundary: 1, custom: 0 }, // sse3 + { sse: 1, opcode: 0xF20F12, e: 1, block_boundary: 1, custom: 1 }, // sse3 + { sse: 1, opcode: 0xF30F12, e: 1, block_boundary: 1, custom: 1 }, // sse3 { sse: 1, opcode: 0x0F13, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F13, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0x0F14, e: 1, custom: 1 }, @@ -641,7 +641,7 @@ const encodings = [ { sse: 1, opcode: 0x660F15, e: 1, custom: 1 }, { sse: 1, opcode: 0x0F16, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F16, reg_ud: 1, e: 1, custom: 1 }, - { sse: 1, opcode: 0xF30F16, e: 1, block_boundary: 1, }, // sse3 + { sse: 1, opcode: 0xF30F16, e: 1, block_boundary: 1, custom: 1 }, // sse3 { sse: 1, opcode: 0x0F17, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F17, reg_ud: 1, e: 1, custom: 1 }, From 8c417d61abb2e0215c48ecd848c3c1e8f7686030 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sat, 2 Sep 2023 19:48:26 +0200 Subject: [PATCH 015/180] Update x86_table.js --- gen/x86_table.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gen/x86_table.js b/gen/x86_table.js index 6c47a43cd8..8f8034963f 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -324,7 +324,7 @@ const encodings = [ { opcode: 0xDC, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDD, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, - { opcode: 0xDD, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, // fisttp (sse3) + { opcode: 0xDD, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, // fisttp (sse3) { opcode: 0xDD, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, { opcode: 0xDD, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, { opcode: 0xDD, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, // frstor @@ -342,7 +342,7 @@ const encodings = [ { opcode: 0xDE, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 0, custom: 0, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDF, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) + { opcode: 0xDF, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) { opcode: 0xDF, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, }, // unimplemented: Binary Coded Decimals @@ -631,8 +631,8 @@ const encodings = [ { sse: 1, opcode: 0xF20F11, e: 1, custom: 1 }, { sse: 1, opcode: 0x0F12, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F12, reg_ud: 1, e: 1, custom: 1 }, - { sse: 1, opcode: 0xF20F12, e: 1, block_boundary: 1, custom: 1 }, // sse3 - { sse: 1, opcode: 0xF30F12, e: 1, block_boundary: 1, custom: 1 }, // sse3 + { sse: 1, opcode: 0xF20F12, e: 1, block_boundary: 1, custom: 0 }, // sse3 + { sse: 1, opcode: 0xF30F12, e: 1, block_boundary: 1, custom: 0 }, // sse3 { sse: 1, opcode: 0x0F13, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F13, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0x0F14, e: 1, custom: 1 }, @@ -641,7 +641,7 @@ const encodings = [ { sse: 1, opcode: 0x660F15, e: 1, custom: 1 }, { sse: 1, opcode: 0x0F16, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F16, reg_ud: 1, e: 1, custom: 1 }, - { sse: 1, opcode: 0xF30F16, e: 1, block_boundary: 1, custom: 1 }, // sse3 + { sse: 1, opcode: 0xF30F16, e: 1, block_boundary: 1, custom: 0 }, // sse3 { sse: 1, opcode: 0x0F17, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F17, reg_ud: 1, e: 1, custom: 1 }, From 011b42d02f4ff78965f86b400dfd2b514dadaeef Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sat, 2 Sep 2023 20:02:10 +0200 Subject: [PATCH 016/180] Update x86_table.js --- gen/x86_table.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen/x86_table.js b/gen/x86_table.js index 8f8034963f..2cd4c79e96 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -631,7 +631,7 @@ const encodings = [ { sse: 1, opcode: 0xF20F11, e: 1, custom: 1 }, { sse: 1, opcode: 0x0F12, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F12, reg_ud: 1, e: 1, custom: 1 }, - { sse: 1, opcode: 0xF20F12, e: 1, block_boundary: 1, custom: 0 }, // sse3 + { sse: 1, opcode: 0xF20F12, e: 1, block_boundary: 1, custom: 1 }, // sse3 { sse: 1, opcode: 0xF30F12, e: 1, block_boundary: 1, custom: 0 }, // sse3 { sse: 1, opcode: 0x0F13, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F13, reg_ud: 1, e: 1, custom: 1 }, From 45f9ae6e6fff0ef8333f0ec3dafb7cec9c838389 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sat, 2 Sep 2023 20:09:33 +0200 Subject: [PATCH 017/180] Update x86_table.js --- gen/x86_table.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gen/x86_table.js b/gen/x86_table.js index 2cd4c79e96..b1365b5aa6 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -632,7 +632,7 @@ const encodings = [ { sse: 1, opcode: 0x0F12, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F12, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0xF20F12, e: 1, block_boundary: 1, custom: 1 }, // sse3 - { sse: 1, opcode: 0xF30F12, e: 1, block_boundary: 1, custom: 0 }, // sse3 + { sse: 1, opcode: 0xF30F12, e: 1, block_boundary: 1, custom: 1 }, // sse3 { sse: 1, opcode: 0x0F13, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F13, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0x0F14, e: 1, custom: 1 }, @@ -641,7 +641,7 @@ const encodings = [ { sse: 1, opcode: 0x660F15, e: 1, custom: 1 }, { sse: 1, opcode: 0x0F16, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F16, reg_ud: 1, e: 1, custom: 1 }, - { sse: 1, opcode: 0xF30F16, e: 1, block_boundary: 1, custom: 0 }, // sse3 + { sse: 1, opcode: 0xF30F16, e: 1, block_boundary: 1, custom: 1 }, // sse3 { sse: 1, opcode: 0x0F17, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F17, reg_ud: 1, e: 1, custom: 1 }, From a7dcb9d726d50b9b31d242124587f35f5c58627b Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sat, 2 Sep 2023 20:20:29 +0200 Subject: [PATCH 018/180] Update x86_table.js --- gen/x86_table.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen/x86_table.js b/gen/x86_table.js index b1365b5aa6..48c38e9e05 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -342,7 +342,7 @@ const encodings = [ { opcode: 0xDE, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 0, custom: 0, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDF, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) + { opcode: 0xDF, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) { opcode: 0xDF, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, }, // unimplemented: Binary Coded Decimals From b5538317b618d66cf026430368e39167b3f7240e Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sat, 2 Sep 2023 20:24:44 +0200 Subject: [PATCH 019/180] Update x86_table.js --- gen/x86_table.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen/x86_table.js b/gen/x86_table.js index 48c38e9e05..b1365b5aa6 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -342,7 +342,7 @@ const encodings = [ { opcode: 0xDE, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 0, custom: 0, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDF, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) + { opcode: 0xDF, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) { opcode: 0xDF, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, }, // unimplemented: Binary Coded Decimals From c4759397928c19a1bcf5711636de951f30f49b35 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sat, 2 Sep 2023 20:30:19 +0200 Subject: [PATCH 020/180] Update x86_table.js --- gen/x86_table.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gen/x86_table.js b/gen/x86_table.js index b1365b5aa6..18807633bb 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -341,8 +341,8 @@ const encodings = [ { opcode: 0xDE, e: 1, fixed_g: 6, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDE, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDF, e: 1, fixed_g: 0, custom: 0, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDF, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) + { opcode: 0xDF, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, }, + { opcode: 0xDF, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) { opcode: 0xDF, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, }, // unimplemented: Binary Coded Decimals From a4617d0a0bda69edfb8684623744772f43cd9298 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sat, 2 Sep 2023 20:37:02 +0200 Subject: [PATCH 021/180] Update x86_table.js --- gen/x86_table.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen/x86_table.js b/gen/x86_table.js index 18807633bb..f53160d242 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -324,7 +324,7 @@ const encodings = [ { opcode: 0xDC, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDD, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, - { opcode: 0xDD, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, // fisttp (sse3) + { opcode: 0xDD, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, // fisttp (sse3) { opcode: 0xDD, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, { opcode: 0xDD, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, { opcode: 0xDD, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, // frstor From bf487bb42cc6a60c54741c1c2bb324282530607d Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sat, 2 Sep 2023 21:11:05 +0200 Subject: [PATCH 022/180] Update jit_instructions.rs --- src/rust/jit_instructions.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/rust/jit_instructions.rs b/src/rust/jit_instructions.rs index 2ce637f67f..22b8538081 100644 --- a/src/rust/jit_instructions.rs +++ b/src/rust/jit_instructions.rs @@ -3852,7 +3852,17 @@ pub fn instr32_DD_0_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_0_reg_jit pub fn instr32_DD_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { instr16_DD_0_mem_jit(ctx, modrm_byte) } - +pub fn instr16_DD_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { + codegen::gen_fpu_load_m64(ctx, modrm_byte); + ctx.builder.call_fn2_i64_i32("fpu_push"); +} +pub fn instr16_DD_1_reg_jit(ctx: &mut JitContext, r: u32) { + codegen::gen_fn1_const(ctx.builder, "fpu_ffree", r); +} +pub fn instr32_DD_1_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_1_reg_jit(ctx, r) } +pub fn instr32_DD_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { + instr16_DD_1_mem_jit(ctx, modrm_byte) +} pub fn instr16_DD_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { codegen::gen_modrm_resolve(ctx, modrm_byte); let address_local = ctx.builder.set_new_local(); From d5908f7c1f098195c90d315859dc41f89da11788 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sat, 2 Sep 2023 21:17:28 +0200 Subject: [PATCH 023/180] Update jit_instructions.rs --- src/rust/jit_instructions.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/rust/jit_instructions.rs b/src/rust/jit_instructions.rs index 22b8538081..ca8cfc9a7c 100644 --- a/src/rust/jit_instructions.rs +++ b/src/rust/jit_instructions.rs @@ -3984,7 +3984,32 @@ pub fn instr_DE_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { pub fn instr_DE_7_reg_jit(ctx: &mut JitContext, r: u32) { instr_group_DE_reg_jit(ctx, r, "fpu_fdivr") } - +pub fn instr_DF_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { + codegen::gen_modrm_resolve(ctx, modrm_byte); + let address_local = ctx.builder.set_new_local(); + codegen::gen_fpu_get_sti(ctx, 0); + ctx.builder.call_fn2_i64_i32_ret("fpu_convert_to_i16"); + let value_local = ctx.builder.set_new_local(); + codegen::gen_safe_write16(ctx, &address_local, &value_local); + ctx.builder.free_local(address_local); + ctx.builder.free_local(value_local); +} +pub fn instr_DF_0_reg_jit(ctx: &mut JitContext, r: u32) { + codegen::gen_fn1_const(ctx.builder, "fpu_fstp", r); +} +pub fn instr_DF_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { + codegen::gen_modrm_resolve(ctx, modrm_byte); + let address_local = ctx.builder.set_new_local(); + codegen::gen_fpu_get_sti(ctx, 0); + ctx.builder.call_fn2_i64_i32_ret("fpu_convert_to_i16"); + let value_local = ctx.builder.set_new_local(); + codegen::gen_safe_write16(ctx, &address_local, &value_local); + ctx.builder.free_local(address_local); + ctx.builder.free_local(value_local); +} +pub fn instr_DF_1_reg_jit(ctx: &mut JitContext, r: u32) { + codegen::gen_fn1_const(ctx.builder, "fpu_fstp", r); +} pub fn instr_DF_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { codegen::gen_modrm_resolve(ctx, modrm_byte); let address_local = ctx.builder.set_new_local(); From 30d62b227cf0ddf6c30edb1271394ce59ae86096 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Mon, 4 Sep 2023 08:05:37 +0200 Subject: [PATCH 024/180] Update x86_table.js --- gen/x86_table.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gen/x86_table.js b/gen/x86_table.js index f53160d242..63dba944f8 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -324,12 +324,12 @@ const encodings = [ { opcode: 0xDC, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDD, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, - { opcode: 0xDD, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, // fisttp (sse3) + { opcode: 0xDD, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, // fisttp (sse3) { opcode: 0xDD, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, { opcode: 0xDD, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, - { opcode: 0xDD, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, // frstor + { opcode: 0xDD, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, skip_mem: 1 }, // frstor { opcode: 0xDD, e: 1, fixed_g: 5, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, - { opcode: 0xDD, e: 1, fixed_g: 6, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, // fsave + { opcode: 0xDD, e: 1, fixed_g: 6, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, skip_mem: 1 }, // fsave { opcode: 0xDD, e: 1, fixed_g: 7, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, { opcode: 0xDE, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, }, @@ -341,11 +341,11 @@ const encodings = [ { opcode: 0xDE, e: 1, fixed_g: 6, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDE, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDF, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDF, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) + { opcode: 0xDF, e: 1, fixed_g: 0, custom: 0, is_fpu: 1, task_switch_test: 1, }, + { opcode: 0xDF, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, skip_mem: 1 }, // fisttp (sse3) { opcode: 0xDF, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDF, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, }, // unimplemented: Binary Coded Decimals + { opcode: 0xDF, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, skip_mem: 1 }, // unimplemented: Binary Coded Decimals { opcode: 0xDF, e: 1, fixed_g: 5, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 6, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, From 23ef03a7843d323ff3176d77a93059ef850c75cf Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Mon, 4 Sep 2023 08:31:49 +0200 Subject: [PATCH 025/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index f7e0ba1bad..38af755555 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1687,7 +1687,6 @@ pub unsafe fn instr_D8_6_mem(addr: i32) { fpu_fdiv(0, return_on_pagefault!(fpu_l pub unsafe fn instr_D8_6_reg(r: i32) { fpu_fdiv(0, fpu_get_sti(r)); } pub unsafe fn instr_D8_7_mem(addr: i32) { fpu_fdivr(0, return_on_pagefault!(fpu_load_m32(addr))); } pub unsafe fn instr_D8_7_reg(r: i32) { fpu_fdivr(0, fpu_get_sti(r)); } - pub unsafe fn instr16_D9_0_mem(addr: i32) { fpu_fldm32(addr); } pub unsafe fn instr16_D9_0_reg(r: i32) { fpu_push(fpu_get_sti(r)); } pub unsafe fn instr16_D9_1_mem(_addr: i32) { @@ -1914,6 +1913,8 @@ pub unsafe fn instr16_DD_6_reg(_r: i32) { trigger_ud(); } pub unsafe fn instr16_DD_7_reg(_r: i32) { trigger_ud(); } pub unsafe fn instr32_DD_0_reg(r: i32) { instr16_DD_0_reg(r) } +#[no_mangle] + #[no_mangle] pub unsafe fn instr32_DD_1_reg(r: i32) { instr16_DD_1_reg(r) } pub unsafe fn instr32_DD_2_reg(r: i32) { instr16_DD_2_reg(r) } @@ -1990,7 +1991,16 @@ pub unsafe fn instr_DE_7_reg(r: i32) { fpu_fdivr(r, fpu_get_sti(r)); fpu_pop(); } - +#[no_mangle] +pub unsafe fn instr_DD_reg(r1: i32, r2: i32) { instr_DD(read_xmm128s(r1), r2); } +pub unsafe fn instr_DD_mem(addr: i32, r: i32) { + instr_DD(return_on_pagefault!(safe_read128s(addr)), r); +} +#[no_mangle] +pub unsafe fn instr_DF_reg(r1: i32, r2: i32) { instr_DF(read_xmm128s(r1), r2); } +pub unsafe fn instr_DF_mem(addr: i32, r: i32) { + instr_DF(return_on_pagefault!(safe_read128s(addr)), r); +} #[no_mangle] pub unsafe fn instr_DF_0_mem(addr: i32) { fpu_fildm16(addr) } #[no_mangle] From 7a6e5c25b8e97294cbbc5f7375c5c9286f56dc3d Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Mon, 4 Sep 2023 09:00:14 +0200 Subject: [PATCH 026/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index 38af755555..2df96cac8a 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -2002,6 +2002,11 @@ pub unsafe fn instr_DF_mem(addr: i32, r: i32) { instr_DF(return_on_pagefault!(safe_read128s(addr)), r); } #[no_mangle] +pub unsafe fn instr_DD_reg(r1: i32, r2: i32) { instr_DD(read_xmm128s(r1), r2); } +pub unsafe fn instr_DD_mem(addr: i32, r: i32) { + instr_DD(return_on_pagefault!(safe_read128s(addr)), r); +} +#[no_mangle] pub unsafe fn instr_DF_0_mem(addr: i32) { fpu_fildm16(addr) } #[no_mangle] pub unsafe fn instr_DF_1_mem(_addr: i32) { From 55488dab66ecbd3bbab98aa041c67691e7f3988b Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Mon, 4 Sep 2023 09:00:59 +0200 Subject: [PATCH 027/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index 2df96cac8a..f45868ab2e 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1991,17 +1991,10 @@ pub unsafe fn instr_DE_7_reg(r: i32) { fpu_fdivr(r, fpu_get_sti(r)); fpu_pop(); } -#[no_mangle] -pub unsafe fn instr_DD_reg(r1: i32, r2: i32) { instr_DD(read_xmm128s(r1), r2); } -pub unsafe fn instr_DD_mem(addr: i32, r: i32) { - instr_DD(return_on_pagefault!(safe_read128s(addr)), r); -} -#[no_mangle] pub unsafe fn instr_DF_reg(r1: i32, r2: i32) { instr_DF(read_xmm128s(r1), r2); } pub unsafe fn instr_DF_mem(addr: i32, r: i32) { instr_DF(return_on_pagefault!(safe_read128s(addr)), r); } -#[no_mangle] pub unsafe fn instr_DD_reg(r1: i32, r2: i32) { instr_DD(read_xmm128s(r1), r2); } pub unsafe fn instr_DD_mem(addr: i32, r: i32) { instr_DD(return_on_pagefault!(safe_read128s(addr)), r); From 23a0a0a28f627eb44006ea8d9c726ed9239ffda4 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Mon, 4 Sep 2023 09:23:46 +0200 Subject: [PATCH 028/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index f45868ab2e..dc483d180a 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1913,8 +1913,6 @@ pub unsafe fn instr16_DD_6_reg(_r: i32) { trigger_ud(); } pub unsafe fn instr16_DD_7_reg(_r: i32) { trigger_ud(); } pub unsafe fn instr32_DD_0_reg(r: i32) { instr16_DD_0_reg(r) } -#[no_mangle] - #[no_mangle] pub unsafe fn instr32_DD_1_reg(r: i32) { instr16_DD_1_reg(r) } pub unsafe fn instr32_DD_2_reg(r: i32) { instr16_DD_2_reg(r) } From 27f747c61c7f56dcf375d0f59ffc45b488e04f94 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Mon, 4 Sep 2023 10:22:41 +0200 Subject: [PATCH 029/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index dc483d180a..25dfa18e40 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1989,21 +1989,20 @@ pub unsafe fn instr_DE_7_reg(r: i32) { fpu_fdivr(r, fpu_get_sti(r)); fpu_pop(); } -pub unsafe fn instr_DF_reg(r1: i32, r2: i32) { instr_DF(read_xmm128s(r1), r2); } -pub unsafe fn instr_DF_mem(addr: i32, r: i32) { - instr_DF(return_on_pagefault!(safe_read128s(addr)), r); +pub unsafe fn instr_DF_1_reg(r: i32) { + fpu_fisttp(r, fpu_get_sti(r)); + fpu_pop(); } -pub unsafe fn instr_DD_reg(r1: i32, r2: i32) { instr_DD(read_xmm128s(r1), r2); } -pub unsafe fn instr_DD_mem(addr: i32, r: i32) { - instr_DD(return_on_pagefault!(safe_read128s(addr)), r); +pub unsafe fn instr_DD_1_reg(r: i32) { + fpu_fisttpl(r, fpu_get_sti(r)); + fpu_pop(); } #[no_mangle] +pub unsafe fn instr_DD_1_mem(addr: i32) { fpu_fisttplm16(addr) } +#[no_mangle] pub unsafe fn instr_DF_0_mem(addr: i32) { fpu_fildm16(addr) } #[no_mangle] -pub unsafe fn instr_DF_1_mem(_addr: i32) { - dbg_log!("fisttp"); - fpu_unimpl(); -} +pub unsafe fn instr_DF_1_mem(addr: i32) { fpu_fisttpm16(addr) } pub unsafe fn instr_DF_2_mem(addr: i32) { fpu_fistm16(addr); } pub unsafe fn instr_DF_3_mem(addr: i32) { fpu_fistm16p(addr); } pub unsafe fn instr_DF_4_mem(_addr: i32) { From f0c16856e988732f43dd54ee9bfd60b9a82e41c1 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Mon, 4 Sep 2023 10:29:04 +0200 Subject: [PATCH 030/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index 25dfa18e40..1991faff36 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1989,7 +1989,7 @@ pub unsafe fn instr_DE_7_reg(r: i32) { fpu_fdivr(r, fpu_get_sti(r)); fpu_pop(); } -pub unsafe fn instr_DF_1_reg(r: i32) { +pub unsafe fn instr_DF_reg(r: i32) { fpu_fisttp(r, fpu_get_sti(r)); fpu_pop(); } @@ -2002,7 +2002,7 @@ pub unsafe fn instr_DD_1_mem(addr: i32) { fpu_fisttplm16(addr) } #[no_mangle] pub unsafe fn instr_DF_0_mem(addr: i32) { fpu_fildm16(addr) } #[no_mangle] -pub unsafe fn instr_DF_1_mem(addr: i32) { fpu_fisttpm16(addr) } +pub unsafe fn instr_DF_mem(addr: i32) { fpu_fisttpm16(addr) } pub unsafe fn instr_DF_2_mem(addr: i32) { fpu_fistm16(addr); } pub unsafe fn instr_DF_3_mem(addr: i32) { fpu_fistm16p(addr); } pub unsafe fn instr_DF_4_mem(_addr: i32) { From 32e8f07a23cbb84aa6c64590543baa0038f62139 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Mon, 4 Sep 2023 11:51:11 +0200 Subject: [PATCH 031/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index 1991faff36..1b93fb6594 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1999,9 +1999,7 @@ pub unsafe fn instr_DD_1_reg(r: i32) { } #[no_mangle] pub unsafe fn instr_DD_1_mem(addr: i32) { fpu_fisttplm16(addr) } -#[no_mangle] pub unsafe fn instr_DF_0_mem(addr: i32) { fpu_fildm16(addr) } -#[no_mangle] pub unsafe fn instr_DF_mem(addr: i32) { fpu_fisttpm16(addr) } pub unsafe fn instr_DF_2_mem(addr: i32) { fpu_fistm16(addr); } pub unsafe fn instr_DF_3_mem(addr: i32) { fpu_fistm16p(addr); } From 9d7ddba3938c3b10191fbdad311c2dacd239f546 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Mon, 4 Sep 2023 12:07:27 +0200 Subject: [PATCH 032/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index 1b93fb6594..48b1b37a19 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -2000,6 +2000,7 @@ pub unsafe fn instr_DD_1_reg(r: i32) { #[no_mangle] pub unsafe fn instr_DD_1_mem(addr: i32) { fpu_fisttplm16(addr) } pub unsafe fn instr_DF_0_mem(addr: i32) { fpu_fildm16(addr) } +pub unsafe fn instr_DF_1_mem(addr: i32) { fpu_fxchm16(addr) } pub unsafe fn instr_DF_mem(addr: i32) { fpu_fisttpm16(addr) } pub unsafe fn instr_DF_2_mem(addr: i32) { fpu_fistm16(addr); } pub unsafe fn instr_DF_3_mem(addr: i32) { fpu_fistm16p(addr); } From ddbbd06cfbb6758f1e7a82f09be16e347213330f Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Mon, 4 Sep 2023 12:23:16 +0200 Subject: [PATCH 033/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index 48b1b37a19..853470b88d 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1879,10 +1879,7 @@ pub unsafe fn instr_DC_7_reg(r: i32) { fpu_fdivr(r, fpu_get_sti(r)); } pub unsafe fn instr16_DD_0_mem(addr: i32) { fpu_fldm64(addr); } #[no_mangle] -pub unsafe fn instr16_DD_1_mem(_addr: i32) { - dbg_log!("fisttp"); - fpu_unimpl(); -} +pub unsafe fn instr16_DD_1_mem(addr: i32) { fpu_fisttpm64(addr); } pub unsafe fn instr16_DD_2_mem(addr: i32) { fpu_fstm64(addr); } pub unsafe fn instr16_DD_3_mem(addr: i32) { fpu_fstm64p(addr); } #[no_mangle] From de68f109887f9b3b85cbb0bc2db7b770f084381b Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Mon, 4 Sep 2023 14:23:37 +0200 Subject: [PATCH 034/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index 853470b88d..b624c89f24 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1820,10 +1820,6 @@ pub unsafe fn instr_DA_7_reg(_r: i32) { trigger_ud(); } pub unsafe fn instr_DB_0_mem(addr: i32) { fpu_fildm32(addr); } #[no_mangle] -pub unsafe fn instr_DB_1_mem(_addr: i32) { - dbg_log!("fisttp"); - fpu_unimpl(); -} pub unsafe fn instr_DB_2_mem(addr: i32) { fpu_fistm32(addr); } pub unsafe fn instr_DB_3_mem(addr: i32) { fpu_fistm32p(addr); } #[no_mangle] From 428f80dd264d4161382de9e2dad9d492e0cec5de Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Mon, 4 Sep 2023 14:30:08 +0200 Subject: [PATCH 035/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index b624c89f24..bcfa15ee7c 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1817,8 +1817,8 @@ pub unsafe fn instr_DA_5_reg(r: i32) { } pub unsafe fn instr_DA_6_reg(_r: i32) { trigger_ud(); } pub unsafe fn instr_DA_7_reg(_r: i32) { trigger_ud(); } - pub unsafe fn instr_DB_0_mem(addr: i32) { fpu_fildm32(addr); } +pub unsafe fn instr_DB_1_mem(addr: i32) { fpu_fisttpm32(addr); } #[no_mangle] pub unsafe fn instr_DB_2_mem(addr: i32) { fpu_fistm32(addr); } pub unsafe fn instr_DB_3_mem(addr: i32) { fpu_fistm32p(addr); } From b6a32fa9315deba29390b3d1c507941cbe4ff8ae Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 5 Sep 2023 14:49:44 +0200 Subject: [PATCH 036/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 43 ++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index bcfa15ee7c..eb0debab96 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1982,19 +1982,44 @@ pub unsafe fn instr_DE_7_reg(r: i32) { fpu_fdivr(r, fpu_get_sti(r)); fpu_pop(); } -pub unsafe fn instr_DF_reg(r: i32) { - fpu_fisttp(r, fpu_get_sti(r)); - fpu_pop(); +#[no_mangle] +pub unsafe fn instr_DF(source: reg128, r: i32) { + // haddps xmm, xmm/mem128 + let destination = read_xmm128s(r); + let result = reg128 { + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], + ], + }; + write_xmm_reg128(r, result); +} +pub unsafe fn instr_DF_reg(r1: i32, r2: i32) { instr_DF(read_xmm128s(r1), r2); } +pub unsafe fn instr_DF_mem(addr: i32, r: i32) { + instr_DF(return_on_pagefault!(safe_read128s(addr)), r); +} +#[no_mangle] +pub unsafe fn instr_DD(source: reg128, r: i32) { + // haddps xmm, xmm/mem128 + let destination = read_xmm128s(r); + let result = reg128 { + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], + ], + }; + write_xmm_reg128(r, result); } -pub unsafe fn instr_DD_1_reg(r: i32) { - fpu_fisttpl(r, fpu_get_sti(r)); - fpu_pop(); +pub unsafe fn instr_DD_reg(r1: i32, r2: i32) { instr_DD(read_xmm128s(r1), r2); } +pub unsafe fn instr_DD_mem(addr: i32, r: i32) { + instr_DD(return_on_pagefault!(safe_read128s(addr)), r); } -#[no_mangle] -pub unsafe fn instr_DD_1_mem(addr: i32) { fpu_fisttplm16(addr) } pub unsafe fn instr_DF_0_mem(addr: i32) { fpu_fildm16(addr) } pub unsafe fn instr_DF_1_mem(addr: i32) { fpu_fxchm16(addr) } -pub unsafe fn instr_DF_mem(addr: i32) { fpu_fisttpm16(addr) } pub unsafe fn instr_DF_2_mem(addr: i32) { fpu_fistm16(addr); } pub unsafe fn instr_DF_3_mem(addr: i32) { fpu_fistm16p(addr); } pub unsafe fn instr_DF_4_mem(_addr: i32) { From 4e418b9396c47bce69ee512f2f7e5e4784f81b40 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 5 Sep 2023 15:55:55 +0200 Subject: [PATCH 037/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index eb0debab96..2ec077fbd7 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1818,7 +1818,6 @@ pub unsafe fn instr_DA_5_reg(r: i32) { pub unsafe fn instr_DA_6_reg(_r: i32) { trigger_ud(); } pub unsafe fn instr_DA_7_reg(_r: i32) { trigger_ud(); } pub unsafe fn instr_DB_0_mem(addr: i32) { fpu_fildm32(addr); } -pub unsafe fn instr_DB_1_mem(addr: i32) { fpu_fisttpm32(addr); } #[no_mangle] pub unsafe fn instr_DB_2_mem(addr: i32) { fpu_fistm32(addr); } pub unsafe fn instr_DB_3_mem(addr: i32) { fpu_fistm32p(addr); } @@ -1875,7 +1874,6 @@ pub unsafe fn instr_DC_7_reg(r: i32) { fpu_fdivr(r, fpu_get_sti(r)); } pub unsafe fn instr16_DD_0_mem(addr: i32) { fpu_fldm64(addr); } #[no_mangle] -pub unsafe fn instr16_DD_1_mem(addr: i32) { fpu_fisttpm64(addr); } pub unsafe fn instr16_DD_2_mem(addr: i32) { fpu_fstm64(addr); } pub unsafe fn instr16_DD_3_mem(addr: i32) { fpu_fstm64p(addr); } #[no_mangle] @@ -2014,6 +2012,18 @@ pub unsafe fn instr_DD(source: reg128, r: i32) { }; write_xmm_reg128(r, result); } +#[no_mangle] +pub unsafe fn instr_DF_1_reg(r: i32) { fpu_fxch(r) } +pub unsafe fn instr_DF_2_reg(r: i32) { fpu_fstp(r); } +pub unsafe fn instr_DF_3_reg(r: i32) { fpu_fstp(r); } +pub unsafe fn instr_DF_4_reg(r: i32) { + if r == 0 { + fpu_fnstsw_reg(); + } + else { + trigger_ud(); + }; +} pub unsafe fn instr_DD_reg(r1: i32, r2: i32) { instr_DD(read_xmm128s(r1), r2); } pub unsafe fn instr_DD_mem(addr: i32, r: i32) { instr_DD(return_on_pagefault!(safe_read128s(addr)), r); @@ -2029,24 +2039,11 @@ pub unsafe fn instr_DF_4_mem(_addr: i32) { pub unsafe fn instr_DF_5_mem(addr: i32) { fpu_fildm64(addr); } pub unsafe fn instr_DF_6_mem(addr: i32) { fpu_fbstp(addr); } pub unsafe fn instr_DF_7_mem(addr: i32) { fpu_fistm64p(addr); } - #[no_mangle] pub unsafe fn instr_DF_0_reg(r: i32) { fpu_ffree(r); fpu_pop(); } -#[no_mangle] -pub unsafe fn instr_DF_1_reg(r: i32) { fpu_fxch(r) } -pub unsafe fn instr_DF_2_reg(r: i32) { fpu_fstp(r); } -pub unsafe fn instr_DF_3_reg(r: i32) { fpu_fstp(r); } -pub unsafe fn instr_DF_4_reg(r: i32) { - if r == 0 { - fpu_fnstsw_reg(); - } - else { - trigger_ud(); - }; -} pub unsafe fn instr_DF_5_reg(r: i32) { fpu_fucomip(r); } pub unsafe fn instr_DF_6_reg(r: i32) { fpu_fcomip(r); } pub unsafe fn instr_DF_7_reg(_r: i32) { trigger_ud(); } From a8b6ae5a1faad50eb79afeb7bddae5c9db2614d3 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 5 Sep 2023 16:07:38 +0200 Subject: [PATCH 038/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 2884 +++++----------------------------- 1 file changed, 416 insertions(+), 2468 deletions(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index 2ec077fbd7..f2f94bbf7b 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1,2544 +1,492 @@ -#![allow(non_snake_case)] +#!/usr/bin/env node +"use strict"; -extern "C" { - fn hlt_op(); -} +const assert = require("assert").strict; +const fs = require("fs"); +const path = require("path"); +const x86_table = require("./x86_table"); +const rust_ast = require("./rust_ast"); +const { hex, mkdirpSync, get_switch_value, get_switch_exist, finalize_table_rust } = require("./util"); -use prefix; -use cpu::arith::*; -use cpu::cpu::*; -use cpu::fpu::*; -use cpu::global_pointers::*; -use cpu::misc_instr::*; -use cpu::misc_instr::{pop16, pop32s, push16, push32}; -use cpu::string::*; -use softfloat::F80; - -pub unsafe fn instr_00_mem(addr: i32, r: i32) { safe_read_write8(addr, &|x| add8(x, read_reg8(r))) } -pub unsafe fn instr_00_reg(r1: i32, r: i32) { write_reg8(r1, add8(read_reg8(r1), read_reg8(r))); } -pub unsafe fn instr16_01_mem(addr: i32, r: i32) { - safe_read_write16(addr, &|x| add16(x, read_reg16(r))) -} -pub unsafe fn instr16_01_reg(r1: i32, r: i32) { - write_reg16(r1, add16(read_reg16(r1), read_reg16(r))); -} -pub unsafe fn instr32_01_mem(addr: i32, r: i32) { - safe_read_write32(addr, &|x| add32(x, read_reg32(r))) -} -pub unsafe fn instr32_01_reg(r1: i32, r: i32) { - write_reg32(r1, add32(read_reg32(r1), read_reg32(r))); -} -pub unsafe fn instr_02_mem(addr: i32, r: i32) { - write_reg8( - r, - add8(read_reg8(r), return_on_pagefault!(safe_read8(addr))), - ); -} -pub unsafe fn instr_02_reg(r1: i32, r: i32) { write_reg8(r, add8(read_reg8(r), read_reg8(r1))); } -pub unsafe fn instr16_03_mem(addr: i32, r: i32) { - write_reg16( - r, - add16(read_reg16(r), return_on_pagefault!(safe_read16(addr))), - ); -} -pub unsafe fn instr16_03_reg(r1: i32, r: i32) { - write_reg16(r, add16(read_reg16(r), read_reg16(r1))); -} -pub unsafe fn instr32_03_mem(addr: i32, r: i32) { - write_reg32( - r, - add32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))), - ); -} -pub unsafe fn instr32_03_reg(r1: i32, r: i32) { - write_reg32(r, add32(read_reg32(r), read_reg32(r1))); -} -pub unsafe fn instr_04(imm8: i32) { write_reg8(AL, add8(read_reg8(AL), imm8)); } -pub unsafe fn instr16_05(imm16: i32) { write_reg16(AX, add16(read_reg16(AX), imm16)); } -pub unsafe fn instr32_05(imm32: i32) { write_reg32(EAX, add32(read_reg32(EAX), imm32)); } -pub unsafe fn instr16_06() { - return_on_pagefault!(push16(*sreg.offset(ES as isize) as i32)); -} -pub unsafe fn instr32_06() { return_on_pagefault!(push32_sreg(ES)) } +const OUT_DIR = path.join(__dirname, "..", "src/rust/gen/"); -#[no_mangle] -pub unsafe fn instr16_07() { - if !switch_seg(ES, return_on_pagefault!(safe_read16(get_stack_pointer(0)))) { - return; - } - adjust_stack_reg(2); -} -#[no_mangle] -pub unsafe fn instr32_07() { - if !switch_seg( - ES, - return_on_pagefault!(safe_read32s(get_stack_pointer(0))) & 0xFFFF, - ) { - return; - } - adjust_stack_reg(4); -} +mkdirpSync(OUT_DIR); -pub unsafe fn instr_08_mem(addr: i32, r: i32) { safe_read_write8(addr, &|x| or8(x, read_reg8(r))) } -pub unsafe fn instr_08_reg(r1: i32, r: i32) { write_reg8(r1, or8(read_reg8(r1), read_reg8(r))); } -pub unsafe fn instr16_09_mem(addr: i32, r: i32) { - safe_read_write16(addr, &|x| or16(x, read_reg16(r))) -} -pub unsafe fn instr16_09_reg(r1: i32, r: i32) { - write_reg16(r1, or16(read_reg16(r1), read_reg16(r))); -} -pub unsafe fn instr32_09_mem(addr: i32, r: i32) { - safe_read_write32(addr, &|x| or32(x, read_reg32(r))) -} -pub unsafe fn instr32_09_reg(r1: i32, r: i32) { - write_reg32(r1, or32(read_reg32(r1), read_reg32(r))); -} -pub unsafe fn instr_0A_mem(addr: i32, r: i32) { - write_reg8(r, or8(read_reg8(r), return_on_pagefault!(safe_read8(addr)))); -} -pub unsafe fn instr_0A_reg(r1: i32, r: i32) { write_reg8(r, or8(read_reg8(r), read_reg8(r1))); } -pub unsafe fn instr16_0B_mem(addr: i32, r: i32) { - write_reg16( - r, - or16(read_reg16(r), return_on_pagefault!(safe_read16(addr))), - ); -} -pub unsafe fn instr16_0B_reg(r1: i32, r: i32) { - write_reg16(r, or16(read_reg16(r), read_reg16(r1))); -} -pub unsafe fn instr32_0B_mem(addr: i32, r: i32) { - write_reg32( - r, - or32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))), - ); -} -pub unsafe fn instr32_0B_reg(r1: i32, r: i32) { - write_reg32(r, or32(read_reg32(r), read_reg32(r1))); -} -pub unsafe fn instr_0C(imm8: i32) { write_reg8(AL, or8(read_reg8(AL), imm8)); } -pub unsafe fn instr16_0D(imm16: i32) { write_reg16(AX, or16(read_reg16(AX), imm16)); } -pub unsafe fn instr32_0D(imm32: i32) { write_reg32(EAX, or32(read_reg32(EAX), imm32)); } +const table_arg = get_switch_value("--table"); +const gen_all = get_switch_exist("--all"); +const to_generate = { + interpreter: gen_all || table_arg === "interpreter", + interpreter0f: gen_all || table_arg === "interpreter0f", +}; -pub unsafe fn instr16_0E() { - return_on_pagefault!(push16(*sreg.offset(CS as isize) as i32)); -} -pub unsafe fn instr32_0E() { return_on_pagefault!(push32_sreg(CS)) } +assert( + Object.keys(to_generate).some(k => to_generate[k]), + "Pass --table [interpreter|interpreter0f] or --all to pick which tables to generate" +); -pub unsafe fn instr16_0F() { run_instruction0f_16(return_on_pagefault!(read_imm8())); } -pub unsafe fn instr32_0F() { run_instruction0f_32(return_on_pagefault!(read_imm8())); } +gen_table(); -pub unsafe fn instr_10_mem(addr: i32, r: i32) { safe_read_write8(addr, &|x| adc8(x, read_reg8(r))) } -pub unsafe fn instr_10_reg(r1: i32, r: i32) { write_reg8(r1, adc8(read_reg8(r1), read_reg8(r))); } -pub unsafe fn instr16_11_mem(addr: i32, r: i32) { - safe_read_write16(addr, &|x| adc16(x, read_reg16(r))) -} -pub unsafe fn instr16_11_reg(r1: i32, r: i32) { - write_reg16(r1, adc16(read_reg16(r1), read_reg16(r))); -} -pub unsafe fn instr32_11_mem(addr: i32, r: i32) { - safe_read_write32(addr, &|x| adc32(x, read_reg32(r))) -} -pub unsafe fn instr32_11_reg(r1: i32, r: i32) { - write_reg32(r1, adc32(read_reg32(r1), read_reg32(r))); -} -pub unsafe fn instr_12_mem(addr: i32, r: i32) { - write_reg8( - r, - adc8(read_reg8(r), return_on_pagefault!(safe_read8(addr))), - ); -} -pub unsafe fn instr_12_reg(r1: i32, r: i32) { write_reg8(r, adc8(read_reg8(r), read_reg8(r1))); } -pub unsafe fn instr16_13_mem(addr: i32, r: i32) { - write_reg16( - r, - adc16(read_reg16(r), return_on_pagefault!(safe_read16(addr))), - ); -} -pub unsafe fn instr16_13_reg(r1: i32, r: i32) { - write_reg16(r, adc16(read_reg16(r), read_reg16(r1))); +function wrap_imm_call(imm) +{ + return `match ${imm} { Ok(o) => o, Err(()) => return }`; } -pub unsafe fn instr32_13_mem(addr: i32, r: i32) { - write_reg32( - r, - adc32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))), - ); -} -pub unsafe fn instr32_13_reg(r1: i32, r: i32) { - write_reg32(r, adc32(read_reg32(r), read_reg32(r1))); -} -pub unsafe fn instr_14(imm8: i32) { write_reg8(AL, adc8(read_reg8(AL), imm8)); } -pub unsafe fn instr16_15(imm16: i32) { write_reg16(AX, adc16(read_reg16(AX), imm16)); } -pub unsafe fn instr32_15(imm32: i32) { write_reg32(EAX, adc32(read_reg32(EAX), imm32)); } -pub unsafe fn instr16_16() { - return_on_pagefault!(push16(*sreg.offset(SS as isize) as i32)); -} -pub unsafe fn instr32_16() { return_on_pagefault!(push32_sreg(SS)) } +function gen_read_imm_call(op, size_variant) +{ + let size = (op.os || op.opcode % 2 === 1) ? size_variant : 8; -#[no_mangle] -pub unsafe fn instr16_17() { - if !switch_seg(SS, return_on_pagefault!(safe_read16(get_stack_pointer(0)))) { - return; + if(op.imm8 || op.imm8s || op.imm16 || op.imm1632 || op.imm32 || op.immaddr) + { + if(op.imm8) + { + return wrap_imm_call("read_imm8()"); + } + else if(op.imm8s) + { + return wrap_imm_call("read_imm8s()"); + } + else + { + if(op.immaddr) + { + // immaddr: depends on address size + return wrap_imm_call("read_moffs()"); + } + else + { + assert(op.imm1632 || op.imm16 || op.imm32); + + if(op.imm1632 && size === 16 || op.imm16) + { + return wrap_imm_call("read_imm16()"); + } + else + { + assert(op.imm1632 && size === 32 || op.imm32); + return wrap_imm_call("read_imm32s()"); + } + } + } } - adjust_stack_reg(2); -} -#[no_mangle] -pub unsafe fn instr32_17() { - if !switch_seg( - SS, - return_on_pagefault!(safe_read32s(get_stack_pointer(0))) & 0xFFFF, - ) { - return; + else + { + return undefined; } - adjust_stack_reg(4); } -pub unsafe fn instr_18_mem(addr: i32, r: i32) { safe_read_write8(addr, &|x| sbb8(x, read_reg8(r))) } -pub unsafe fn instr_18_reg(r1: i32, r: i32) { write_reg8(r1, sbb8(read_reg8(r1), read_reg8(r))); } -pub unsafe fn instr16_19_mem(addr: i32, r: i32) { - safe_read_write16(addr, &|x| sbb16(x, read_reg16(r))) -} -pub unsafe fn instr16_19_reg(r1: i32, r: i32) { - write_reg16(r1, sbb16(read_reg16(r1), read_reg16(r))); -} -pub unsafe fn instr32_19_mem(addr: i32, r: i32) { - safe_read_write32(addr, &|x| sbb32(x, read_reg32(r))) -} -pub unsafe fn instr32_19_reg(r1: i32, r: i32) { - write_reg32(r1, sbb32(read_reg32(r1), read_reg32(r))); -} -pub unsafe fn instr_1A_mem(addr: i32, r: i32) { - write_reg8( - r, - sbb8(read_reg8(r), return_on_pagefault!(safe_read8(addr))), - ); -} -pub unsafe fn instr_1A_reg(r1: i32, r: i32) { write_reg8(r, sbb8(read_reg8(r), read_reg8(r1))); } -pub unsafe fn instr16_1B_mem(addr: i32, r: i32) { - write_reg16( - r, - sbb16(read_reg16(r), return_on_pagefault!(safe_read16(addr))), - ); -} -pub unsafe fn instr16_1B_reg(r1: i32, r: i32) { - write_reg16(r, sbb16(read_reg16(r), read_reg16(r1))); -} -pub unsafe fn instr32_1B_mem(addr: i32, r: i32) { - write_reg32( - r, - sbb32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))), - ); +function gen_call(name, args) +{ + args = args || []; + return `${name}(${args.join(", ")});`; } -pub unsafe fn instr32_1B_reg(r1: i32, r: i32) { - write_reg32(r, sbb32(read_reg32(r), read_reg32(r1))); -} -pub unsafe fn instr_1C(imm8: i32) { write_reg8(AL, sbb8(read_reg8(AL), imm8)); } -pub unsafe fn instr16_1D(imm16: i32) { write_reg16(AX, sbb16(read_reg16(AX), imm16)); } -pub unsafe fn instr32_1D(imm32: i32) { write_reg32(EAX, sbb32(read_reg32(EAX), imm32)); } -pub unsafe fn instr16_1E() { - return_on_pagefault!(push16(*sreg.offset(DS as isize) as i32)); -} -pub unsafe fn instr32_1E() { return_on_pagefault!(push32_sreg(DS)) } +/* + * Current naming scheme: + * instr(16|32|)_(66|F2|F3)?0F?[0-9a-f]{2}(_[0-7])?(_mem|_reg|) + */ +function make_instruction_name(encoding, size) +{ + const suffix = encoding.os ? String(size) : ""; + const opcode_hex = hex(encoding.opcode & 0xFF, 2); + const first_prefix = (encoding.opcode & 0xFF00) === 0 ? "" : hex(encoding.opcode >> 8 & 0xFF, 2); + const second_prefix = (encoding.opcode & 0xFF0000) === 0 ? "" : hex(encoding.opcode >> 16 & 0xFF, 2); + const fixed_g_suffix = encoding.fixed_g === undefined ? "" : `_${encoding.fixed_g}`; + const module = first_prefix === "0F" || second_prefix === "0F" ? "instructions_0f" : "instructions"; -#[no_mangle] -pub unsafe fn instr16_1F() { - if !switch_seg(DS, return_on_pagefault!(safe_read16(get_stack_pointer(0)))) { - return; - } - adjust_stack_reg(2); -} -#[no_mangle] -pub unsafe fn instr32_1F() { - if !switch_seg( - DS, - return_on_pagefault!(safe_read32s(get_stack_pointer(0))) & 0xFFFF, - ) { - return; - } - adjust_stack_reg(4); -} + assert(first_prefix === "" || first_prefix === "0F" || first_prefix === "F2" || first_prefix === "F3"); + assert(second_prefix === "" || second_prefix === "66" || second_prefix === "F2" || second_prefix === "F3"); -pub unsafe fn instr_20_mem(addr: i32, r: i32) { safe_read_write8(addr, &|x| and8(x, read_reg8(r))) } -pub unsafe fn instr_20_reg(r1: i32, r: i32) { write_reg8(r1, and8(read_reg8(r1), read_reg8(r))); } -pub unsafe fn instr16_21_mem(addr: i32, r: i32) { - safe_read_write16(addr, &|x| and16(x, read_reg16(r))) -} -pub unsafe fn instr16_21_reg(r1: i32, r: i32) { - write_reg16(r1, and16(read_reg16(r1), read_reg16(r))); -} -pub unsafe fn instr32_21_mem(addr: i32, r: i32) { - safe_read_write32(addr, &|x| and32(x, read_reg32(r))) + return `${module}::instr${suffix}_${second_prefix}${first_prefix}${opcode_hex}${fixed_g_suffix}`; } -pub unsafe fn instr32_21_reg(r1: i32, r: i32) { - write_reg32(r1, and32(read_reg32(r1), read_reg32(r))); -} -pub unsafe fn instr_22_mem(addr: i32, r: i32) { - write_reg8( - r, - and8(read_reg8(r), return_on_pagefault!(safe_read8(addr))), - ); -} -pub unsafe fn instr_22_reg(r1: i32, r: i32) { write_reg8(r, and8(read_reg8(r), read_reg8(r1))); } -pub unsafe fn instr16_23_mem(addr: i32, r: i32) { - write_reg16( - r, - and16(read_reg16(r), return_on_pagefault!(safe_read16(addr))), - ); -} -pub unsafe fn instr16_23_reg(r1: i32, r: i32) { - write_reg16(r, and16(read_reg16(r), read_reg16(r1))); -} -pub unsafe fn instr32_23_mem(addr: i32, r: i32) { - write_reg32( - r, - and32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))), - ); -} -pub unsafe fn instr32_23_reg(r1: i32, r: i32) { - write_reg32(r, and32(read_reg32(r), read_reg32(r1))); -} -pub unsafe fn instr_24(imm8: i32) { write_reg8(AL, and8(read_reg8(AL), imm8)); } -pub unsafe fn instr16_25(imm16: i32) { write_reg16(AX, and16(read_reg16(AX), imm16)); } -pub unsafe fn instr32_25(imm32: i32) { write_reg32(EAX, and32(read_reg32(EAX), imm32)); } -pub unsafe fn instr_26() { segment_prefix_op(ES); } +function gen_instruction_body(encodings, size) +{ + const encoding = encodings[0]; -#[no_mangle] -pub unsafe fn instr_27() { bcd_daa(); } + let has_66 = []; + let has_F2 = []; + let has_F3 = []; + let no_prefix = []; -pub unsafe fn instr_28_mem(addr: i32, r: i32) { safe_read_write8(addr, &|x| sub8(x, read_reg8(r))) } -pub unsafe fn instr_28_reg(r1: i32, r: i32) { write_reg8(r1, sub8(read_reg8(r1), read_reg8(r))); } -pub unsafe fn instr16_29_mem(addr: i32, r: i32) { - safe_read_write16(addr, &|x| sub16(x, read_reg16(r))) -} -pub unsafe fn instr16_29_reg(r1: i32, r: i32) { - write_reg16(r1, sub16(read_reg16(r1), read_reg16(r))); -} -pub unsafe fn instr32_29_mem(addr: i32, r: i32) { - safe_read_write32(addr, &|x| sub32(x, read_reg32(r))) -} -pub unsafe fn instr32_29_reg(r1: i32, r: i32) { - write_reg32(r1, sub32(read_reg32(r1), read_reg32(r))); -} -pub unsafe fn instr_2A_mem(addr: i32, r: i32) { - write_reg8( - r, - sub8(read_reg8(r), return_on_pagefault!(safe_read8(addr))), - ); -} -pub unsafe fn instr_2A_reg(r1: i32, r: i32) { write_reg8(r, sub8(read_reg8(r), read_reg8(r1))); } -pub unsafe fn instr16_2B_mem(addr: i32, r: i32) { - write_reg16( - r, - sub16(read_reg16(r), return_on_pagefault!(safe_read16(addr))), - ); -} -pub unsafe fn instr16_2B_reg(r1: i32, r: i32) { - write_reg16(r, sub16(read_reg16(r), read_reg16(r1))); -} -pub unsafe fn instr32_2B_mem(addr: i32, r: i32) { - write_reg32( - r, - sub32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))), - ); -} -pub unsafe fn instr32_2B_reg(r1: i32, r: i32) { - write_reg32(r, sub32(read_reg32(r), read_reg32(r1))); -} -pub unsafe fn instr_2C(imm8: i32) { write_reg8(AL, sub8(read_reg8(AL), imm8)); } -pub unsafe fn instr16_2D(imm16: i32) { write_reg16(AX, sub16(read_reg16(AX), imm16)); } -pub unsafe fn instr32_2D(imm32: i32) { write_reg32(EAX, sub32(read_reg32(EAX), imm32)); } - -pub unsafe fn instr_2E() { segment_prefix_op(CS); } - -#[no_mangle] -pub unsafe fn instr_2F() { bcd_das(); } - -pub unsafe fn instr_30_mem(addr: i32, r: i32) { safe_read_write8(addr, &|x| xor8(x, read_reg8(r))) } -pub unsafe fn instr_30_reg(r1: i32, r: i32) { write_reg8(r1, xor8(read_reg8(r1), read_reg8(r))); } -pub unsafe fn instr16_31_mem(addr: i32, r: i32) { - safe_read_write16(addr, &|x| xor16(x, read_reg16(r))) -} -pub unsafe fn instr16_31_reg(r1: i32, r: i32) { - write_reg16(r1, xor16(read_reg16(r1), read_reg16(r))); -} -pub unsafe fn instr32_31_mem(addr: i32, r: i32) { - safe_read_write32(addr, &|x| xor32(x, read_reg32(r))) -} -pub unsafe fn instr32_31_reg(r1: i32, r: i32) { - write_reg32(r1, xor32(read_reg32(r1), read_reg32(r))); -} -pub unsafe fn instr_32_mem(addr: i32, r: i32) { - write_reg8( - r, - xor8(read_reg8(r), return_on_pagefault!(safe_read8(addr))), - ); -} -pub unsafe fn instr_32_reg(r1: i32, r: i32) { write_reg8(r, xor8(read_reg8(r), read_reg8(r1))); } -pub unsafe fn instr16_33_mem(addr: i32, r: i32) { - write_reg16( - r, - xor16(read_reg16(r), return_on_pagefault!(safe_read16(addr))), - ); -} -pub unsafe fn instr16_33_reg(r1: i32, r: i32) { - write_reg16(r, xor16(read_reg16(r), read_reg16(r1))); -} -pub unsafe fn instr32_33_mem(addr: i32, r: i32) { - write_reg32( - r, - xor32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))), - ); -} -pub unsafe fn instr32_33_reg(r1: i32, r: i32) { - write_reg32(r, xor32(read_reg32(r), read_reg32(r1))); -} -pub unsafe fn instr_34(imm8: i32) { write_reg8(AL, xor8(read_reg8(AL), imm8)); } -pub unsafe fn instr16_35(imm16: i32) { write_reg16(AX, xor16(read_reg16(AX), imm16)); } -pub unsafe fn instr32_35(imm32: i32) { write_reg32(EAX, xor32(read_reg32(EAX), imm32)); } - -pub unsafe fn instr_36() { segment_prefix_op(SS); } - -#[no_mangle] -pub unsafe fn instr_37() { bcd_aaa(); } - -pub unsafe fn instr_38_mem(addr: i32, r: i32) { - cmp8(return_on_pagefault!(safe_read8(addr)), read_reg8(r)); -} -pub unsafe fn instr_38_reg(r1: i32, r: i32) { cmp8(read_reg8(r1), read_reg8(r)); } -pub unsafe fn instr16_39_mem(addr: i32, r: i32) { - cmp16(return_on_pagefault!(safe_read16(addr)), read_reg16(r)); -} -pub unsafe fn instr16_39_reg(r1: i32, r: i32) { cmp16(read_reg16(r1), read_reg16(r)); } -pub unsafe fn instr32_39_mem(addr: i32, r: i32) { - cmp32(return_on_pagefault!(safe_read32s(addr)), read_reg32(r)); -} -pub unsafe fn instr32_39_reg(r1: i32, r: i32) { cmp32(read_reg32(r1), read_reg32(r)); } -pub unsafe fn instr_3A_mem(addr: i32, r: i32) { - cmp8(read_reg8(r), return_on_pagefault!(safe_read8(addr))); -} -pub unsafe fn instr_3A_reg(r1: i32, r: i32) { cmp8(read_reg8(r), read_reg8(r1)); } -pub unsafe fn instr16_3B_mem(addr: i32, r: i32) { - cmp16(read_reg16(r), return_on_pagefault!(safe_read16(addr))); -} -pub unsafe fn instr16_3B_reg(r1: i32, r: i32) { cmp16(read_reg16(r), read_reg16(r1)); } -pub unsafe fn instr32_3B_mem(addr: i32, r: i32) { - cmp32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))); -} -pub unsafe fn instr32_3B_reg(r1: i32, r: i32) { cmp32(read_reg32(r), read_reg32(r1)); } -pub unsafe fn instr_3C(imm8: i32) { cmp8(read_reg8(AL), imm8); } -pub unsafe fn instr16_3D(imm16: i32) { cmp16(read_reg16(AX), imm16); } -pub unsafe fn instr32_3D(imm32: i32) { cmp32(read_reg32(EAX), imm32); } - -pub unsafe fn instr_3E() { segment_prefix_op(DS); } - -#[no_mangle] -pub unsafe fn instr_3F() { bcd_aas(); } - -pub unsafe fn instr16_40() { write_reg16(AX, inc16(read_reg16(AX))); } -pub unsafe fn instr32_40() { write_reg32(EAX, inc32(read_reg32(EAX))); } -pub unsafe fn instr16_41() { write_reg16(CX, inc16(read_reg16(CX))); } -pub unsafe fn instr32_41() { write_reg32(ECX, inc32(read_reg32(ECX))); } -pub unsafe fn instr16_42() { write_reg16(DX, inc16(read_reg16(DX))); } -pub unsafe fn instr32_42() { write_reg32(EDX, inc32(read_reg32(EDX))); } -pub unsafe fn instr16_43() { write_reg16(BX, inc16(read_reg16(BX))); } -pub unsafe fn instr32_43() { write_reg32(EBX, inc32(read_reg32(EBX))); } -pub unsafe fn instr16_44() { write_reg16(SP, inc16(read_reg16(SP))); } -pub unsafe fn instr32_44() { write_reg32(ESP, inc32(read_reg32(ESP))); } -pub unsafe fn instr16_45() { write_reg16(BP, inc16(read_reg16(BP))); } -pub unsafe fn instr32_45() { write_reg32(EBP, inc32(read_reg32(EBP))); } -pub unsafe fn instr16_46() { write_reg16(SI, inc16(read_reg16(SI))); } -pub unsafe fn instr32_46() { write_reg32(ESI, inc32(read_reg32(ESI))); } -pub unsafe fn instr16_47() { write_reg16(DI, inc16(read_reg16(DI))); } -pub unsafe fn instr32_47() { write_reg32(EDI, inc32(read_reg32(EDI))); } -pub unsafe fn instr16_48() { write_reg16(AX, dec16(read_reg16(AX))); } -pub unsafe fn instr32_48() { write_reg32(EAX, dec32(read_reg32(EAX))); } -pub unsafe fn instr16_49() { write_reg16(CX, dec16(read_reg16(CX))); } -pub unsafe fn instr32_49() { write_reg32(ECX, dec32(read_reg32(ECX))); } -pub unsafe fn instr16_4A() { write_reg16(DX, dec16(read_reg16(DX))); } -pub unsafe fn instr32_4A() { write_reg32(EDX, dec32(read_reg32(EDX))); } -pub unsafe fn instr16_4B() { write_reg16(BX, dec16(read_reg16(BX))); } -pub unsafe fn instr32_4B() { write_reg32(EBX, dec32(read_reg32(EBX))); } -pub unsafe fn instr16_4C() { write_reg16(SP, dec16(read_reg16(SP))); } -pub unsafe fn instr32_4C() { write_reg32(ESP, dec32(read_reg32(ESP))); } -pub unsafe fn instr16_4D() { write_reg16(BP, dec16(read_reg16(BP))); } -pub unsafe fn instr32_4D() { write_reg32(EBP, dec32(read_reg32(EBP))); } -pub unsafe fn instr16_4E() { write_reg16(SI, dec16(read_reg16(SI))); } -pub unsafe fn instr32_4E() { write_reg32(ESI, dec32(read_reg32(ESI))); } -pub unsafe fn instr16_4F() { write_reg16(DI, dec16(read_reg16(DI))); } -pub unsafe fn instr32_4F() { write_reg32(EDI, dec32(read_reg32(EDI))); } - -pub unsafe fn push16_reg(r: i32) { - return_on_pagefault!(push16(read_reg16(r))); -} -pub unsafe fn push32_reg(r: i32) { - return_on_pagefault!(push32(read_reg32(r))); -} - -pub unsafe fn instr16_50() { push16_reg(AX) } -pub unsafe fn instr32_50() { push32_reg(EAX) } -pub unsafe fn instr16_51() { push16_reg(CX) } -pub unsafe fn instr32_51() { push32_reg(ECX) } -pub unsafe fn instr16_52() { push16_reg(DX) } -pub unsafe fn instr32_52() { push32_reg(EDX) } -pub unsafe fn instr16_53() { push16_reg(BX) } -pub unsafe fn instr32_53() { push32_reg(EBX) } -pub unsafe fn instr16_54() { push16_reg(SP) } -pub unsafe fn instr32_54() { push32_reg(ESP) } -pub unsafe fn instr16_55() { push16_reg(BP) } -pub unsafe fn instr32_55() { push32_reg(EBP) } -pub unsafe fn instr16_56() { push16_reg(SI) } -pub unsafe fn instr32_56() { push32_reg(ESI) } -pub unsafe fn instr16_57() { push16_reg(DI) } -pub unsafe fn instr32_57() { push32_reg(EDI) } -pub unsafe fn instr16_58() { write_reg16(AX, return_on_pagefault!(pop16())); } -pub unsafe fn instr32_58() { write_reg32(EAX, return_on_pagefault!(pop32s())); } -pub unsafe fn instr16_59() { write_reg16(CX, return_on_pagefault!(pop16())); } -pub unsafe fn instr32_59() { write_reg32(ECX, return_on_pagefault!(pop32s())); } -pub unsafe fn instr16_5A() { write_reg16(DX, return_on_pagefault!(pop16())); } -pub unsafe fn instr32_5A() { write_reg32(EDX, return_on_pagefault!(pop32s())); } -pub unsafe fn instr16_5B() { write_reg16(BX, return_on_pagefault!(pop16())); } -pub unsafe fn instr32_5B() { write_reg32(EBX, return_on_pagefault!(pop32s())); } -pub unsafe fn instr16_5C() { - write_reg16(SP, return_on_pagefault!(safe_read16(get_stack_pointer(0)))); -} -pub unsafe fn instr32_5C() { - write_reg32( - ESP, - return_on_pagefault!(safe_read32s(get_stack_pointer(0))), - ); -} -pub unsafe fn instr16_5D() { write_reg16(BP, return_on_pagefault!(pop16())); } -pub unsafe fn instr32_5D() { write_reg32(EBP, return_on_pagefault!(pop32s())); } -pub unsafe fn instr16_5E() { write_reg16(SI, return_on_pagefault!(pop16())); } -pub unsafe fn instr32_5E() { write_reg32(ESI, return_on_pagefault!(pop32s())); } -pub unsafe fn instr16_5F() { write_reg16(DI, return_on_pagefault!(pop16())); } -pub unsafe fn instr32_5F() { write_reg32(EDI, return_on_pagefault!(pop32s())); } - -#[no_mangle] -pub unsafe fn instr16_60() { pusha16(); } -#[no_mangle] -pub unsafe fn instr32_60() { pusha32(); } -#[no_mangle] -pub unsafe fn instr16_61() { popa16(); } -#[no_mangle] -pub unsafe fn instr32_61() { popa32(); } - -#[no_mangle] -pub unsafe fn instr_62_reg(_r2: i32, _r: i32) { - // bound - dbg_log!("Unimplemented BOUND instruction"); - dbg_assert!(false); -} -#[no_mangle] -pub unsafe fn instr_62_mem(_addr: i32, _r: i32) { - dbg_log!("Unimplemented BOUND instruction"); - dbg_assert!(false); -} - -pub unsafe fn arpl(seg: i32, r16: i32) -> i32 { - *flags_changed &= !FLAG_ZERO; - - if (seg & 3) < (r16 & 3) { - *flags |= FLAG_ZERO; - seg & !3 | r16 & 3 - } - else { - *flags &= !FLAG_ZERO; - seg + for(let e of encodings) + { + if((e.opcode >>> 16) === 0x66) has_66.push(e); + else if((e.opcode >>> 8 & 0xFF) === 0xF2 || (e.opcode >>> 16) === 0xF2) has_F2.push(e); + else if((e.opcode >>> 8 & 0xFF) === 0xF3 || (e.opcode >>> 16) === 0xF3) has_F3.push(e); + else no_prefix.push(e); } -} -#[no_mangle] -pub unsafe fn instr_63_mem(addr: i32, r: i32) { - if !*protected_mode || vm86_mode() { - dbg_log!("arpl #ud"); - trigger_ud(); - return; - } - safe_read_write16(addr, &|x| arpl(x, read_reg16(r))) -} -#[no_mangle] -pub unsafe fn instr_63_reg(r1: i32, r: i32) { - if !*protected_mode || vm86_mode() { - dbg_log!("arpl #ud"); - trigger_ud(); - return; + if(has_F2.length || has_F3.length) + { + assert((encoding.opcode & 0xFF0000) === 0 || (encoding.opcode & 0xFF00) === 0x0F00); } - write_reg16(r1, arpl(read_reg16(r1), read_reg16(r))); -} -pub unsafe fn instr_64() { segment_prefix_op(FS); } -pub unsafe fn instr_65() { segment_prefix_op(GS); } - -pub unsafe fn instr_66() { - // Operand-size override prefix - *prefixes |= prefix::PREFIX_MASK_OPSIZE; - run_prefix_instruction(); - *prefixes = 0; -} -pub unsafe fn instr_67() { - // Address-size override prefix - dbg_assert!(is_asize_32() == *is_32); - *prefixes |= prefix::PREFIX_MASK_ADDRSIZE; - run_prefix_instruction(); - *prefixes = 0; -} - -pub unsafe fn instr16_68(imm16: i32) { - return_on_pagefault!(push16(imm16)); -} -pub unsafe fn instr32_68(imm32: i32) { - return_on_pagefault!(push32(imm32)); -} -pub unsafe fn instr16_69_mem(addr: i32, r: i32, imm: i32) { - write_reg16(r, imul_reg16(return_on_pagefault!(safe_read16(addr)), imm)); -} -pub unsafe fn instr16_69_reg(r1: i32, r: i32, imm: i32) { - write_reg16(r, imul_reg16(read_reg16(r1), imm)); -} -pub unsafe fn instr32_69_mem(addr: i32, r: i32, imm: i32) { - write_reg32(r, imul_reg32(return_on_pagefault!(safe_read32s(addr)), imm)); -} -pub unsafe fn instr32_69_reg(r1: i32, r: i32, imm: i32) { - write_reg32(r, imul_reg32(read_reg32(r1), imm)); -} - -pub unsafe fn instr16_6A(imm8: i32) { - return_on_pagefault!(push16(imm8)); -} -pub unsafe fn instr32_6A(imm8: i32) { - return_on_pagefault!(push32(imm8)); -} -pub unsafe fn instr16_6B_mem(addr: i32, r: i32, imm: i32) { - write_reg16(r, imul_reg16(return_on_pagefault!(safe_read16(addr)), imm)); -} -pub unsafe fn instr16_6B_reg(r1: i32, r: i32, imm: i32) { - write_reg16(r, imul_reg16(read_reg16(r1), imm)); -} -pub unsafe fn instr32_6B_mem(addr: i32, r: i32, imm: i32) { - write_reg32(r, imul_reg32(return_on_pagefault!(safe_read32s(addr)), imm)); -} -pub unsafe fn instr32_6B_reg(r1: i32, r: i32, imm: i32) { - write_reg32(r, imul_reg32(read_reg32(r1), imm)); -} - -pub unsafe fn instr_6C() { insb_no_rep(is_asize_32()); } -pub unsafe fn instr_F26C() { insb_rep(is_asize_32()); } -pub unsafe fn instr_F36C() { insb_rep(is_asize_32()); } -pub unsafe fn instr16_6D() { insw_no_rep(is_asize_32()); } -pub unsafe fn instr32_6D() { insd_no_rep(is_asize_32()); } -pub unsafe fn instr16_F26D() { insw_rep(is_asize_32()); } -pub unsafe fn instr16_F36D() { insw_rep(is_asize_32()); } -pub unsafe fn instr32_F26D() { insd_rep(is_asize_32()); } -pub unsafe fn instr32_F36D() { insd_rep(is_asize_32()); } - -pub unsafe fn instr_6E() { outsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } -pub unsafe fn instr_F26E() { outsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } -pub unsafe fn instr_F36E() { outsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } - -pub unsafe fn instr16_6F() { - outsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); -} -pub unsafe fn instr32_6F() { - outsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); -} -pub unsafe fn instr16_F26F() { outsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } -pub unsafe fn instr16_F36F() { outsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } -pub unsafe fn instr32_F26F() { outsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } -pub unsafe fn instr32_F36F() { outsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } - -pub unsafe fn instr16_70(imm8: i32) { jmpcc16(test_o(), imm8); } -pub unsafe fn instr16_71(imm8: i32) { jmpcc16(!test_o(), imm8); } -pub unsafe fn instr16_72(imm8: i32) { jmpcc16(test_b(), imm8); } -pub unsafe fn instr16_73(imm8: i32) { jmpcc16(!test_b(), imm8); } -pub unsafe fn instr16_74(imm8: i32) { jmpcc16(test_z(), imm8); } -pub unsafe fn instr16_75(imm8: i32) { jmpcc16(!test_z(), imm8); } -pub unsafe fn instr16_76(imm8: i32) { jmpcc16(test_be(), imm8); } -pub unsafe fn instr16_77(imm8: i32) { jmpcc16(!test_be(), imm8); } -pub unsafe fn instr16_78(imm8: i32) { jmpcc16(test_s(), imm8); } -pub unsafe fn instr16_79(imm8: i32) { jmpcc16(!test_s(), imm8); } -pub unsafe fn instr16_7A(imm8: i32) { jmpcc16(test_p(), imm8); } -pub unsafe fn instr16_7B(imm8: i32) { jmpcc16(!test_p(), imm8); } -pub unsafe fn instr16_7C(imm8: i32) { jmpcc16(test_l(), imm8); } -pub unsafe fn instr16_7D(imm8: i32) { jmpcc16(!test_l(), imm8); } -pub unsafe fn instr16_7E(imm8: i32) { jmpcc16(test_le(), imm8); } -pub unsafe fn instr16_7F(imm8: i32) { jmpcc16(!test_le(), imm8); } -pub unsafe fn instr32_70(imm8: i32) { jmpcc32(test_o(), imm8); } -pub unsafe fn instr32_71(imm8: i32) { jmpcc32(!test_o(), imm8); } -pub unsafe fn instr32_72(imm8: i32) { jmpcc32(test_b(), imm8); } -pub unsafe fn instr32_73(imm8: i32) { jmpcc32(!test_b(), imm8); } -pub unsafe fn instr32_74(imm8: i32) { jmpcc32(test_z(), imm8); } -pub unsafe fn instr32_75(imm8: i32) { jmpcc32(!test_z(), imm8); } -pub unsafe fn instr32_76(imm8: i32) { jmpcc32(test_be(), imm8); } -pub unsafe fn instr32_77(imm8: i32) { jmpcc32(!test_be(), imm8); } -pub unsafe fn instr32_78(imm8: i32) { jmpcc32(test_s(), imm8); } -pub unsafe fn instr32_79(imm8: i32) { jmpcc32(!test_s(), imm8); } -pub unsafe fn instr32_7A(imm8: i32) { jmpcc32(test_p(), imm8); } -pub unsafe fn instr32_7B(imm8: i32) { jmpcc32(!test_p(), imm8); } -pub unsafe fn instr32_7C(imm8: i32) { jmpcc32(test_l(), imm8); } -pub unsafe fn instr32_7D(imm8: i32) { jmpcc32(!test_l(), imm8); } -pub unsafe fn instr32_7E(imm8: i32) { jmpcc32(test_le(), imm8); } -pub unsafe fn instr32_7F(imm8: i32) { jmpcc32(!test_le(), imm8); } - -pub unsafe fn instr_80_0_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| add8(x, imm)) } -pub unsafe fn instr_80_0_reg(r1: i32, imm: i32) { write_reg8(r1, add8(read_reg8(r1), imm)); } -pub unsafe fn instr_80_1_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| or8(x, imm)) } -pub unsafe fn instr_80_1_reg(r1: i32, imm: i32) { write_reg8(r1, or8(read_reg8(r1), imm)); } -pub unsafe fn instr_80_2_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| adc8(x, imm)) } -pub unsafe fn instr_80_2_reg(r1: i32, imm: i32) { write_reg8(r1, adc8(read_reg8(r1), imm)); } -pub unsafe fn instr_80_3_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| sbb8(x, imm)) } -pub unsafe fn instr_80_3_reg(r1: i32, imm: i32) { write_reg8(r1, sbb8(read_reg8(r1), imm)); } -pub unsafe fn instr_80_4_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| and8(x, imm)) } -pub unsafe fn instr_80_4_reg(r1: i32, imm: i32) { write_reg8(r1, and8(read_reg8(r1), imm)); } -pub unsafe fn instr_80_5_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| sub8(x, imm)) } -pub unsafe fn instr_80_5_reg(r1: i32, imm: i32) { write_reg8(r1, sub8(read_reg8(r1), imm)); } -pub unsafe fn instr_80_6_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| xor8(x, imm)) } -pub unsafe fn instr_80_6_reg(r1: i32, imm: i32) { write_reg8(r1, xor8(read_reg8(r1), imm)); } -pub unsafe fn instr_80_7_reg(r: i32, imm: i32) { cmp8(read_reg8(r), imm); } -pub unsafe fn instr_80_7_mem(addr: i32, imm: i32) { - cmp8(return_on_pagefault!(safe_read8(addr)), imm); -} -pub unsafe fn instr16_81_0_mem(addr: i32, imm: i32) { safe_read_write16(addr, &|x| add16(x, imm)) } -pub unsafe fn instr16_81_0_reg(r1: i32, imm: i32) { write_reg16(r1, add16(read_reg16(r1), imm)); } -pub unsafe fn instr16_81_1_mem(addr: i32, imm: i32) { safe_read_write16(addr, &|x| or16(x, imm)) } -pub unsafe fn instr16_81_1_reg(r1: i32, imm: i32) { write_reg16(r1, or16(read_reg16(r1), imm)); } -pub unsafe fn instr16_81_2_mem(addr: i32, imm: i32) { safe_read_write16(addr, &|x| adc16(x, imm)) } -pub unsafe fn instr16_81_2_reg(r1: i32, imm: i32) { write_reg16(r1, adc16(read_reg16(r1), imm)); } -pub unsafe fn instr16_81_3_mem(addr: i32, imm: i32) { safe_read_write16(addr, &|x| sbb16(x, imm)) } -pub unsafe fn instr16_81_3_reg(r1: i32, imm: i32) { write_reg16(r1, sbb16(read_reg16(r1), imm)); } -pub unsafe fn instr16_81_4_mem(addr: i32, imm: i32) { safe_read_write16(addr, &|x| and16(x, imm)) } -pub unsafe fn instr16_81_4_reg(r1: i32, imm: i32) { write_reg16(r1, and16(read_reg16(r1), imm)); } -pub unsafe fn instr16_81_5_mem(addr: i32, imm: i32) { safe_read_write16(addr, &|x| sub16(x, imm)) } -pub unsafe fn instr16_81_5_reg(r1: i32, imm: i32) { write_reg16(r1, sub16(read_reg16(r1), imm)); } -pub unsafe fn instr16_81_6_mem(addr: i32, imm: i32) { safe_read_write16(addr, &|x| xor16(x, imm)) } -pub unsafe fn instr16_81_6_reg(r1: i32, imm: i32) { write_reg16(r1, xor16(read_reg16(r1), imm)); } -pub unsafe fn instr16_81_7_reg(r: i32, imm: i32) { cmp16(read_reg16(r), imm); } -pub unsafe fn instr16_81_7_mem(addr: i32, imm: i32) { - cmp16(return_on_pagefault!(safe_read16(addr)), imm); -} -pub unsafe fn instr32_81_0_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| add32(x, imm)) } -pub unsafe fn instr32_81_0_reg(r1: i32, imm: i32) { write_reg32(r1, add32(read_reg32(r1), imm)); } -pub unsafe fn instr32_81_1_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| or32(x, imm)) } -pub unsafe fn instr32_81_1_reg(r1: i32, imm: i32) { write_reg32(r1, or32(read_reg32(r1), imm)); } -pub unsafe fn instr32_81_2_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| adc32(x, imm)) } -pub unsafe fn instr32_81_2_reg(r1: i32, imm: i32) { write_reg32(r1, adc32(read_reg32(r1), imm)); } -pub unsafe fn instr32_81_3_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| sbb32(x, imm)) } -pub unsafe fn instr32_81_3_reg(r1: i32, imm: i32) { write_reg32(r1, sbb32(read_reg32(r1), imm)); } -pub unsafe fn instr32_81_4_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| and32(x, imm)) } -pub unsafe fn instr32_81_4_reg(r1: i32, imm: i32) { write_reg32(r1, and32(read_reg32(r1), imm)); } -pub unsafe fn instr32_81_5_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| sub32(x, imm)) } -pub unsafe fn instr32_81_5_reg(r1: i32, imm: i32) { write_reg32(r1, sub32(read_reg32(r1), imm)); } -pub unsafe fn instr32_81_6_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| xor32(x, imm)) } -pub unsafe fn instr32_81_6_reg(r1: i32, imm: i32) { write_reg32(r1, xor32(read_reg32(r1), imm)); } -pub unsafe fn instr32_81_7_reg(r: i32, imm: i32) { cmp32(read_reg32(r), imm); } -pub unsafe fn instr32_81_7_mem(addr: i32, imm: i32) { - cmp32(return_on_pagefault!(safe_read32s(addr)), imm); -} -pub unsafe fn instr_82_0_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| add8(x, imm)) } -pub unsafe fn instr_82_0_reg(r1: i32, imm: i32) { write_reg8(r1, add8(read_reg8(r1), imm)); } -pub unsafe fn instr_82_1_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| or8(x, imm)) } -pub unsafe fn instr_82_1_reg(r1: i32, imm: i32) { write_reg8(r1, or8(read_reg8(r1), imm)); } -pub unsafe fn instr_82_2_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| adc8(x, imm)) } -pub unsafe fn instr_82_2_reg(r1: i32, imm: i32) { write_reg8(r1, adc8(read_reg8(r1), imm)); } -pub unsafe fn instr_82_3_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| sbb8(x, imm)) } -pub unsafe fn instr_82_3_reg(r1: i32, imm: i32) { write_reg8(r1, sbb8(read_reg8(r1), imm)); } -pub unsafe fn instr_82_4_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| and8(x, imm)) } -pub unsafe fn instr_82_4_reg(r1: i32, imm: i32) { write_reg8(r1, and8(read_reg8(r1), imm)); } -pub unsafe fn instr_82_5_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| sub8(x, imm)) } -pub unsafe fn instr_82_5_reg(r1: i32, imm: i32) { write_reg8(r1, sub8(read_reg8(r1), imm)); } -pub unsafe fn instr_82_6_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| xor8(x, imm)) } -pub unsafe fn instr_82_6_reg(r1: i32, imm: i32) { write_reg8(r1, xor8(read_reg8(r1), imm)); } -pub unsafe fn instr_82_7_reg(r: i32, imm: i32) { cmp8(read_reg8(r), imm); } -pub unsafe fn instr_82_7_mem(addr: i32, imm: i32) { - cmp8(return_on_pagefault!(safe_read8(addr)), imm); -} -pub unsafe fn instr16_83_0_mem(addr: i32, imm: i32) { - safe_read_write16(addr, &|x| add16(x, imm & 0xFFFF)) -} -pub unsafe fn instr16_83_0_reg(r1: i32, imm: i32) { - write_reg16(r1, add16(read_reg16(r1), imm & 0xFFFF)); -} -pub unsafe fn instr16_83_1_mem(addr: i32, imm: i32) { - safe_read_write16(addr, &|x| or16(x, imm & 0xFFFF)) -} -pub unsafe fn instr16_83_1_reg(r1: i32, imm: i32) { - write_reg16(r1, or16(read_reg16(r1), imm & 0xFFFF)); -} -pub unsafe fn instr16_83_2_mem(addr: i32, imm: i32) { - safe_read_write16(addr, &|x| adc16(x, imm & 0xFFFF)) -} -pub unsafe fn instr16_83_2_reg(r1: i32, imm: i32) { - write_reg16(r1, adc16(read_reg16(r1), imm & 0xFFFF)); -} -pub unsafe fn instr16_83_3_mem(addr: i32, imm: i32) { - safe_read_write16(addr, &|x| sbb16(x, imm & 0xFFFF)) -} -pub unsafe fn instr16_83_3_reg(r1: i32, imm: i32) { - write_reg16(r1, sbb16(read_reg16(r1), imm & 0xFFFF)); -} -pub unsafe fn instr16_83_4_mem(addr: i32, imm: i32) { - safe_read_write16(addr, &|x| and16(x, imm & 0xFFFF)) -} -pub unsafe fn instr16_83_4_reg(r1: i32, imm: i32) { - write_reg16(r1, and16(read_reg16(r1), imm & 0xFFFF)); -} -pub unsafe fn instr16_83_5_mem(addr: i32, imm: i32) { - safe_read_write16(addr, &|x| sub16(x, imm & 0xFFFF)) -} -pub unsafe fn instr16_83_5_reg(r1: i32, imm: i32) { - write_reg16(r1, sub16(read_reg16(r1), imm & 0xFFFF)); -} -pub unsafe fn instr16_83_6_mem(addr: i32, imm: i32) { - safe_read_write16(addr, &|x| xor16(x, imm & 0xFFFF)) -} -pub unsafe fn instr16_83_6_reg(r1: i32, imm: i32) { - write_reg16(r1, xor16(read_reg16(r1), imm & 0xFFFF)); -} -pub unsafe fn instr16_83_7_reg(r: i32, imm: i32) { cmp16(read_reg16(r), imm & 0xFFFF); } -pub unsafe fn instr16_83_7_mem(addr: i32, imm: i32) { - cmp16(return_on_pagefault!(safe_read16(addr)), imm & 0xFFFF); -} + if(has_66.length) + { + assert((encoding.opcode & 0xFF00) === 0x0F00); + } -pub unsafe fn instr32_83_0_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| add32(x, imm)) } -pub unsafe fn instr32_83_0_reg(r1: i32, imm: i32) { write_reg32(r1, add32(read_reg32(r1), imm)); } -pub unsafe fn instr32_83_1_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| or32(x, imm)) } -pub unsafe fn instr32_83_1_reg(r1: i32, imm: i32) { write_reg32(r1, or32(read_reg32(r1), imm)); } -pub unsafe fn instr32_83_2_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| adc32(x, imm)) } -pub unsafe fn instr32_83_2_reg(r1: i32, imm: i32) { write_reg32(r1, adc32(read_reg32(r1), imm)); } -pub unsafe fn instr32_83_3_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| sbb32(x, imm)) } -pub unsafe fn instr32_83_3_reg(r1: i32, imm: i32) { write_reg32(r1, sbb32(read_reg32(r1), imm)); } -pub unsafe fn instr32_83_4_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| and32(x, imm)) } -pub unsafe fn instr32_83_4_reg(r1: i32, imm: i32) { write_reg32(r1, and32(read_reg32(r1), imm)); } -pub unsafe fn instr32_83_5_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| sub32(x, imm)) } -pub unsafe fn instr32_83_5_reg(r1: i32, imm: i32) { write_reg32(r1, sub32(read_reg32(r1), imm)); } -pub unsafe fn instr32_83_6_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| xor32(x, imm)) } -pub unsafe fn instr32_83_6_reg(r1: i32, imm: i32) { write_reg32(r1, xor32(read_reg32(r1), imm)); } -pub unsafe fn instr32_83_7_reg(r: i32, imm: i32) { cmp32(read_reg32(r), imm); } -pub unsafe fn instr32_83_7_mem(addr: i32, imm: i32) { - cmp32(return_on_pagefault!(safe_read32s(addr)), imm); -} + const code = []; -pub unsafe fn instr_84_mem(addr: i32, r: i32) { - test8(return_on_pagefault!(safe_read8(addr)), read_reg8(r)); -} -pub unsafe fn instr_84_reg(r1: i32, r: i32) { test8(read_reg8(r1), read_reg8(r)); } -pub unsafe fn instr16_85_mem(addr: i32, r: i32) { - test16(return_on_pagefault!(safe_read16(addr)), read_reg16(r)); -} -pub unsafe fn instr16_85_reg(r1: i32, r: i32) { test16(read_reg16(r1), read_reg16(r)); } -pub unsafe fn instr32_85_mem(addr: i32, r: i32) { - test32(return_on_pagefault!(safe_read32s(addr)), read_reg32(r)); -} -pub unsafe fn instr32_85_reg(r1: i32, r: i32) { test32(read_reg32(r1), read_reg32(r)); } -pub unsafe fn instr_86_mem(addr: i32, r: i32) { safe_read_write8(addr, &|x| xchg8(x, r)) } -pub unsafe fn instr_86_reg(r1: i32, r: i32) { write_reg8(r1, xchg8(read_reg8(r1), r)); } -pub unsafe fn instr16_87_mem(addr: i32, r: i32) { safe_read_write16(addr, &|x| xchg16(x, r)) } -pub unsafe fn instr16_87_reg(r1: i32, r: i32) { write_reg16(r1, xchg16(read_reg16(r1), r)); } -pub unsafe fn instr32_87_mem(addr: i32, r: i32) { safe_read_write32(addr, &|x| xchg32(x, r)) } -pub unsafe fn instr32_87_reg(r1: i32, r: i32) { write_reg32(r1, xchg32(read_reg32(r1), r)); } -pub unsafe fn instr_88_reg(r2: i32, r: i32) { write_reg8(r2, read_reg8(r)); } -pub unsafe fn instr_88_mem(addr: i32, r: i32) { - return_on_pagefault!(safe_write8(addr, read_reg8(r))); -} -pub unsafe fn instr16_89_reg(r2: i32, r: i32) { write_reg16(r2, read_reg16(r)); } -pub unsafe fn instr16_89_mem(addr: i32, r: i32) { - return_on_pagefault!(safe_write16(addr, read_reg16(r))); -} -pub unsafe fn instr32_89_reg(r2: i32, r: i32) { write_reg32(r2, read_reg32(r)); } -pub unsafe fn instr32_89_mem(addr: i32, r: i32) { - return_on_pagefault!(safe_write32(addr, read_reg32(r))); -} -pub unsafe fn instr_8A_mem(addr: i32, r: i32) { - write_reg8(r, return_on_pagefault!(safe_read8(addr))); -} -pub unsafe fn instr_8A_reg(r1: i32, r: i32) { write_reg8(r, read_reg8(r1)); } -pub unsafe fn instr16_8B_mem(addr: i32, r: i32) { - write_reg16(r, return_on_pagefault!(safe_read16(addr))); -} -pub unsafe fn instr16_8B_reg(r1: i32, r: i32) { write_reg16(r, read_reg16(r1)); } -pub unsafe fn instr32_8B_mem(addr: i32, r: i32) { - write_reg32(r, return_on_pagefault!(safe_read32s(addr))); -} -pub unsafe fn instr32_8B_reg(r1: i32, r: i32) { write_reg32(r, read_reg32(r1)); } - -pub unsafe fn instr_8C_check_sreg(seg: i32) -> bool { - if seg >= 6 { - dbg_log!("mov sreg #ud"); - trigger_ud(); - return false; + if(encoding.e) + { + code.push(`let modrm_byte = ${wrap_imm_call("read_imm8()")};`); } - else { - return true; - }; -} -pub unsafe fn instr16_8C_reg(r: i32, seg: i32) { - if instr_8C_check_sreg(seg) { - write_reg16(r, *sreg.offset(seg as isize) as i32); - }; -} -pub unsafe fn instr16_8C_mem(addr: i32, seg: i32) { - if instr_8C_check_sreg(seg) { - return_on_pagefault!(safe_write16(addr, *sreg.offset(seg as isize) as i32)); - }; -} -pub unsafe fn instr32_8C_reg(r: i32, seg: i32) { - if instr_8C_check_sreg(seg) { - write_reg32(r, *sreg.offset(seg as isize) as i32); - }; -} -pub unsafe fn instr32_8C_mem(addr: i32, seg: i32) { - if instr_8C_check_sreg(seg) { - return_on_pagefault!(safe_write16(addr, *sreg.offset(seg as isize) as i32)); - }; -} -pub unsafe fn instr16_8D_reg(_r: i32, _r2: i32) { - dbg_log!("lea #ud"); - trigger_ud(); -} -pub unsafe fn instr16_8D_mem(modrm_byte: i32, r: i32) { - // lea - *prefixes |= prefix::SEG_PREFIX_ZERO; - if let Ok(addr) = modrm_resolve(modrm_byte) { - write_reg16(r, addr); - } - *prefixes = 0; -} -pub unsafe fn instr32_8D_reg(_r: i32, _r2: i32) { - dbg_log!("lea #ud"); - trigger_ud(); -} -pub unsafe fn instr32_8D_mem(modrm_byte: i32, r: i32) { - // lea - // override prefix, so modrm_resolve does not return the segment part - *prefixes |= prefix::SEG_PREFIX_ZERO; - if let Ok(addr) = modrm_resolve(modrm_byte) { - write_reg32(r, addr); - } - *prefixes = 0; -} + if(has_66.length || has_F2.length || has_F3.length) + { + const if_blocks = []; -#[no_mangle] -pub unsafe fn instr_8E_mem(addr: i32, r: i32) { - if r == ES || r == SS || r == DS || r == FS || r == GS { - if !switch_seg(r, return_on_pagefault!(safe_read16(addr))) { - return; + if(has_66.length) { + const body = gen_instruction_body_after_prefix(has_66, size); + if_blocks.push({ condition: "prefixes_ & ::prefix::PREFIX_66 != 0", body, }); } - } - else { - dbg_log!("mov sreg #ud"); - trigger_ud(); - } -} -#[no_mangle] -pub unsafe fn instr_8E_reg(r1: i32, r: i32) { - if r == ES || r == SS || r == DS || r == FS || r == GS { - switch_seg(r, read_reg16(r1)); - } - else { - dbg_log!("mov sreg #ud"); - trigger_ud(); - } -} - -pub unsafe fn instr16_8F_0_mem(modrm_byte: i32) { - // pop - // Update esp *before* resolving the address - adjust_stack_reg(2); - match modrm_resolve(modrm_byte) { - Err(()) => { - // a pagefault happened, reset esp - adjust_stack_reg(-2); - }, - Ok(addr) => { - adjust_stack_reg(-2); - let stack_value = return_on_pagefault!(safe_read16(get_stack_pointer(0))); - return_on_pagefault!(safe_write16(addr, stack_value)); - adjust_stack_reg(2); - }, - } -} -pub unsafe fn instr16_8F_0_reg(r: i32) { write_reg16(r, return_on_pagefault!(pop16())); } -pub unsafe fn instr32_8F_0_mem(modrm_byte: i32) { - // Update esp *before* resolving the address - adjust_stack_reg(4); - match modrm_resolve(modrm_byte) { - Err(()) => { - // a pagefault happened, reset esp - adjust_stack_reg(-4); - }, - Ok(addr) => { - adjust_stack_reg(-4); - let stack_value = return_on_pagefault!(safe_read32s(get_stack_pointer(0))); - return_on_pagefault!(safe_write32(addr, stack_value)); - adjust_stack_reg(4); - }, - } -} -pub unsafe fn instr32_8F_0_reg(r: i32) { write_reg32(r, return_on_pagefault!(pop32s())); } - -pub unsafe fn instr_90() {} -pub unsafe fn instr16_91() { xchg16r(CX); } -pub unsafe fn instr32_91() { xchg32r(ECX); } -pub unsafe fn instr16_92() { xchg16r(DX); } -pub unsafe fn instr32_92() { xchg32r(EDX); } -pub unsafe fn instr16_93() { xchg16r(BX); } -pub unsafe fn instr32_93() { xchg32r(EBX); } -pub unsafe fn instr16_94() { xchg16r(SP); } -pub unsafe fn instr32_94() { xchg32r(ESP); } -pub unsafe fn instr16_95() { xchg16r(BP); } -pub unsafe fn instr32_95() { xchg32r(EBP); } -pub unsafe fn instr16_96() { xchg16r(SI); } -pub unsafe fn instr32_96() { xchg32r(ESI); } -pub unsafe fn instr16_97() { xchg16r(DI); } -pub unsafe fn instr32_97() { xchg32r(EDI); } - -pub unsafe fn instr16_98() { write_reg16(AX, read_reg8(AL) << 24 >> 24); } -pub unsafe fn instr32_98() { write_reg32(EAX, read_reg16(AX) as i16 as i32); } -pub unsafe fn instr16_99() { write_reg16(DX, read_reg16(AX) as i16 as i32 >> 15); } -pub unsafe fn instr32_99() { write_reg32(EDX, read_reg32(EAX) >> 31); } - -#[no_mangle] -pub unsafe fn instr16_9A(new_ip: i32, new_cs: i32) { - // callf - far_jump(new_ip, new_cs, true, false); - dbg_assert!(*is_32 || get_real_eip() < 0x10000); -} -#[no_mangle] -pub unsafe fn instr32_9A(new_ip: i32, new_cs: i32) { - if !*protected_mode || vm86_mode() { - if 0 != new_ip as u32 & 0xFFFF0000 { - dbg_assert!(false); + if(has_F2.length) { + const body = gen_instruction_body_after_prefix(has_F2, size); + if_blocks.push({ condition: "prefixes_ & ::prefix::PREFIX_F2 != 0", body, }); + } + if(has_F3.length) { + const body = gen_instruction_body_after_prefix(has_F3, size); + if_blocks.push({ condition: "prefixes_ & ::prefix::PREFIX_F3 != 0", body, }); } - } - far_jump(new_ip, new_cs, true, true); - dbg_assert!(*is_32 || get_real_eip() < 0x10000); -} -#[no_mangle] -pub unsafe fn instr_9B() { - // fwait: check for pending fpu exceptions - if *cr & (CR0_MP | CR0_TS) == CR0_MP | CR0_TS { - // Note: Different from task_switch_test - // Triggers when TS and MP bits are set (EM bit is ignored) - trigger_nm(); - } - else { - fwait(); - }; -} -unsafe fn instr_pushf_popf_check() -> bool { 0 != *flags & FLAG_VM && getiopl() < 3 } -pub unsafe fn instr16_9C() { - // pushf - if instr_pushf_popf_check() { - dbg_assert!(*protected_mode); - dbg_log!("pushf #gp"); - trigger_gp(0); - } - else { - return_on_pagefault!(push16(get_eflags())); - }; -} -pub unsafe fn instr32_9C() { - // pushf - if instr_pushf_popf_check() { - // trap to virtual 8086 monitor - dbg_assert!(*protected_mode); - dbg_log!("pushf #gp"); - trigger_gp(0); - } - else { - // vm and rf flag are cleared in image stored on the stack - return_on_pagefault!(push32(get_eflags() & 0xFCFFFF)); - }; -} - -pub unsafe fn instr16_9D() { - // popf - if instr_pushf_popf_check() { - dbg_log!("popf #gp"); - trigger_gp(0); - return; - } - let old_eflags = *flags; - update_eflags(*flags & !0xFFFF | return_on_pagefault!(pop16())); - if old_eflags & FLAG_INTERRUPT == 0 && *flags & FLAG_INTERRUPT != 0 { - handle_irqs(); - } -} -pub unsafe fn instr32_9D() { - // popf - if instr_pushf_popf_check() { - dbg_log!("popf #gp"); - trigger_gp(0); - return; - } - let old_eflags = *flags; - update_eflags(return_on_pagefault!(pop32s())); - if old_eflags & FLAG_INTERRUPT == 0 && *flags & FLAG_INTERRUPT != 0 { - handle_irqs(); - } -} - -pub unsafe fn instr_9E() { - // sahf - *flags = *flags & !255 | read_reg8(AH); - *flags = *flags & FLAGS_MASK | FLAGS_DEFAULT; - *flags_changed &= !255; -} -pub unsafe fn instr_9F() { - // lahf - write_reg8(AH, get_eflags()); -} - -pub unsafe fn instr_A0(moffs: i32) { - // mov - let data = return_on_pagefault!(safe_read8(return_on_pagefault!(get_seg_prefix_ds(moffs)))); - write_reg8(AL, data); -} -pub unsafe fn instr16_A1(moffs: i32) { - // mov - let data = return_on_pagefault!(safe_read16(return_on_pagefault!(get_seg_prefix_ds(moffs)))); - write_reg16(AX, data); -} -pub unsafe fn instr32_A1(moffs: i32) { - let data = return_on_pagefault!(safe_read32s(return_on_pagefault!(get_seg_prefix_ds(moffs)))); - write_reg32(EAX, data); -} -pub unsafe fn instr_A2(moffs: i32) { - // mov - return_on_pagefault!(safe_write8( - return_on_pagefault!(get_seg_prefix_ds(moffs)), - read_reg8(AL) - )); -} -pub unsafe fn instr16_A3(moffs: i32) { - // mov - return_on_pagefault!(safe_write16( - return_on_pagefault!(get_seg_prefix_ds(moffs)), - read_reg16(AX) - )); -} -pub unsafe fn instr32_A3(moffs: i32) { - return_on_pagefault!(safe_write32( - return_on_pagefault!(get_seg_prefix_ds(moffs)), - read_reg32(EAX) - )); -} - -pub unsafe fn instr_A4() { movsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } -pub unsafe fn instr_F2A4() { movsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } -pub unsafe fn instr_F3A4() { movsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } - -pub unsafe fn instr16_A5() { - movsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); -} -pub unsafe fn instr32_A5() { - movsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); -} -pub unsafe fn instr16_F2A5() { movsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } -pub unsafe fn instr16_F3A5() { movsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } -pub unsafe fn instr32_F2A5() { movsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } -pub unsafe fn instr32_F3A5() { movsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } - -pub unsafe fn instr_A6() { cmpsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } -pub unsafe fn instr_F2A6() { cmpsb_repnz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } -pub unsafe fn instr_F3A6() { cmpsb_repz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } -pub unsafe fn instr16_A7() { - cmpsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); -} -pub unsafe fn instr32_A7() { - cmpsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); -} -pub unsafe fn instr16_F2A7() { - cmpsw_repnz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); -} -pub unsafe fn instr16_F3A7() { - cmpsw_repz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); -} -pub unsafe fn instr32_F2A7() { - cmpsd_repnz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); -} -pub unsafe fn instr32_F3A7() { - cmpsd_repz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); -} - -pub unsafe fn instr_A8(imm8: i32) { test8(read_reg8(AL), imm8); } -pub unsafe fn instr16_A9(imm16: i32) { test16(read_reg16(AX), imm16); } -pub unsafe fn instr32_A9(imm32: i32) { test32(read_reg32(EAX), imm32); } - -pub unsafe fn instr_AA() { stosb_no_rep(is_asize_32()); } -pub unsafe fn instr_F2AA() { stosb_rep(is_asize_32()); } -pub unsafe fn instr_F3AA() { stosb_rep(is_asize_32()); } - -pub unsafe fn instr16_AB() { stosw_no_rep(is_asize_32()); } -pub unsafe fn instr32_AB() { stosd_no_rep(is_asize_32()); } -pub unsafe fn instr16_F2AB() { stosw_rep(is_asize_32()); } -pub unsafe fn instr16_F3AB() { stosw_rep(is_asize_32()); } -pub unsafe fn instr32_F2AB() { stosd_rep(is_asize_32()); } -pub unsafe fn instr32_F3AB() { stosd_rep(is_asize_32()); } - -pub unsafe fn instr_AC() { lodsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } -pub unsafe fn instr_F2AC() { lodsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } -pub unsafe fn instr_F3AC() { lodsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } - -pub unsafe fn instr16_AD() { - lodsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); -} -pub unsafe fn instr32_AD() { - lodsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); -} -pub unsafe fn instr16_F2AD() { lodsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } -pub unsafe fn instr16_F3AD() { lodsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } -pub unsafe fn instr32_F2AD() { lodsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } -pub unsafe fn instr32_F3AD() { lodsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } - -pub unsafe fn instr_AE() { scasb_no_rep(is_asize_32()); } -pub unsafe fn instr_F2AE() { scasb_repnz(is_asize_32()); } -pub unsafe fn instr_F3AE() { scasb_repz(is_asize_32()); } - -pub unsafe fn instr16_AF() { scasw_no_rep(is_asize_32()); } -pub unsafe fn instr32_AF() { scasd_no_rep(is_asize_32()); } -pub unsafe fn instr16_F2AF() { scasw_repnz(is_asize_32()); } -pub unsafe fn instr16_F3AF() { scasw_repz(is_asize_32()); } -pub unsafe fn instr32_F2AF() { scasd_repnz(is_asize_32()); } -pub unsafe fn instr32_F3AF() { scasd_repz(is_asize_32()); } - -pub unsafe fn instr_B0(imm8: i32) { write_reg8(AL, imm8); } -pub unsafe fn instr_B1(imm8: i32) { write_reg8(CL, imm8); } -pub unsafe fn instr_B2(imm8: i32) { write_reg8(DL, imm8); } -pub unsafe fn instr_B3(imm8: i32) { write_reg8(BL, imm8); } -pub unsafe fn instr_B4(imm8: i32) { write_reg8(AH, imm8); } -pub unsafe fn instr_B5(imm8: i32) { write_reg8(CH, imm8); } -pub unsafe fn instr_B6(imm8: i32) { write_reg8(DH, imm8); } -pub unsafe fn instr_B7(imm8: i32) { write_reg8(BH, imm8); } -pub unsafe fn instr16_B8(imm: i32) { write_reg16(AX, imm); } -pub unsafe fn instr32_B8(imm: i32) { write_reg32(EAX, imm); } -pub unsafe fn instr16_B9(imm: i32) { write_reg16(CX, imm); } -pub unsafe fn instr32_B9(imm: i32) { write_reg32(ECX, imm); } -pub unsafe fn instr16_BA(imm: i32) { write_reg16(DX, imm); } -pub unsafe fn instr32_BA(imm: i32) { write_reg32(EDX, imm); } -pub unsafe fn instr16_BB(imm: i32) { write_reg16(BX, imm); } -pub unsafe fn instr32_BB(imm: i32) { write_reg32(EBX, imm); } -pub unsafe fn instr16_BC(imm: i32) { write_reg16(SP, imm); } -pub unsafe fn instr32_BC(imm: i32) { write_reg32(ESP, imm); } -pub unsafe fn instr16_BD(imm: i32) { write_reg16(BP, imm); } -pub unsafe fn instr32_BD(imm: i32) { write_reg32(EBP, imm); } -pub unsafe fn instr16_BE(imm: i32) { write_reg16(SI, imm); } -pub unsafe fn instr32_BE(imm: i32) { write_reg32(ESI, imm); } -pub unsafe fn instr16_BF(imm: i32) { write_reg16(DI, imm); } -pub unsafe fn instr32_BF(imm: i32) { write_reg32(EDI, imm); } - -pub unsafe fn instr_C0_0_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| rol8(x, imm & 31)) } -pub unsafe fn instr_C0_0_reg(r1: i32, imm: i32) { write_reg8(r1, rol8(read_reg8(r1), imm & 31)); } -pub unsafe fn instr_C0_1_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| ror8(x, imm & 31)) } -pub unsafe fn instr_C0_1_reg(r1: i32, imm: i32) { write_reg8(r1, ror8(read_reg8(r1), imm & 31)); } -pub unsafe fn instr_C0_2_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| rcl8(x, imm & 31)) } -pub unsafe fn instr_C0_2_reg(r1: i32, imm: i32) { write_reg8(r1, rcl8(read_reg8(r1), imm & 31)); } -pub unsafe fn instr_C0_3_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| rcr8(x, imm & 31)) } -pub unsafe fn instr_C0_3_reg(r1: i32, imm: i32) { write_reg8(r1, rcr8(read_reg8(r1), imm & 31)); } -pub unsafe fn instr_C0_4_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| shl8(x, imm & 31)) } -pub unsafe fn instr_C0_4_reg(r1: i32, imm: i32) { write_reg8(r1, shl8(read_reg8(r1), imm & 31)); } -pub unsafe fn instr_C0_5_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| shr8(x, imm & 31)) } -pub unsafe fn instr_C0_5_reg(r1: i32, imm: i32) { write_reg8(r1, shr8(read_reg8(r1), imm & 31)); } -pub unsafe fn instr_C0_6_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| shl8(x, imm & 31)) } -pub unsafe fn instr_C0_6_reg(r1: i32, imm: i32) { write_reg8(r1, shl8(read_reg8(r1), imm & 31)); } -pub unsafe fn instr_C0_7_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| sar8(x, imm & 31)) } -pub unsafe fn instr_C0_7_reg(r1: i32, imm: i32) { write_reg8(r1, sar8(read_reg8(r1), imm & 31)); } -pub unsafe fn instr16_C1_0_mem(addr: i32, imm: i32) { - safe_read_write16(addr, &|x| rol16(x, imm & 31)) -} -pub unsafe fn instr16_C1_0_reg(r1: i32, imm: i32) { - write_reg16(r1, rol16(read_reg16(r1), imm & 31)); -} -pub unsafe fn instr16_C1_1_mem(addr: i32, imm: i32) { - safe_read_write16(addr, &|x| ror16(x, imm & 31)) -} -pub unsafe fn instr16_C1_1_reg(r1: i32, imm: i32) { - write_reg16(r1, ror16(read_reg16(r1), imm & 31)); -} -pub unsafe fn instr16_C1_2_mem(addr: i32, imm: i32) { - safe_read_write16(addr, &|x| rcl16(x, imm & 31)) -} -pub unsafe fn instr16_C1_2_reg(r1: i32, imm: i32) { - write_reg16(r1, rcl16(read_reg16(r1), imm & 31)); -} -pub unsafe fn instr16_C1_3_mem(addr: i32, imm: i32) { - safe_read_write16(addr, &|x| rcr16(x, imm & 31)) -} -pub unsafe fn instr16_C1_3_reg(r1: i32, imm: i32) { - write_reg16(r1, rcr16(read_reg16(r1), imm & 31)); -} -pub unsafe fn instr16_C1_4_mem(addr: i32, imm: i32) { - safe_read_write16(addr, &|x| shl16(x, imm & 31)) -} -pub unsafe fn instr16_C1_4_reg(r1: i32, imm: i32) { - write_reg16(r1, shl16(read_reg16(r1), imm & 31)); -} -pub unsafe fn instr16_C1_5_mem(addr: i32, imm: i32) { - safe_read_write16(addr, &|x| shr16(x, imm & 31)) -} -pub unsafe fn instr16_C1_5_reg(r1: i32, imm: i32) { - write_reg16(r1, shr16(read_reg16(r1), imm & 31)); -} -pub unsafe fn instr16_C1_6_mem(addr: i32, imm: i32) { - safe_read_write16(addr, &|x| shl16(x, imm & 31)) -} -pub unsafe fn instr16_C1_6_reg(r1: i32, imm: i32) { - write_reg16(r1, shl16(read_reg16(r1), imm & 31)); -} -pub unsafe fn instr16_C1_7_mem(addr: i32, imm: i32) { - safe_read_write16(addr, &|x| sar16(x, imm & 31)) -} -pub unsafe fn instr16_C1_7_reg(r1: i32, imm: i32) { - write_reg16(r1, sar16(read_reg16(r1), imm & 31)); -} -pub unsafe fn instr32_C1_0_mem(addr: i32, imm: i32) { - safe_read_write32(addr, &|x| rol32(x, imm & 31)) -} -pub unsafe fn instr32_C1_0_reg(r1: i32, imm: i32) { - write_reg32(r1, rol32(read_reg32(r1), imm & 31)); -} -pub unsafe fn instr32_C1_1_mem(addr: i32, imm: i32) { - safe_read_write32(addr, &|x| ror32(x, imm & 31)) -} -pub unsafe fn instr32_C1_1_reg(r1: i32, imm: i32) { - write_reg32(r1, ror32(read_reg32(r1), imm & 31)); -} -pub unsafe fn instr32_C1_2_mem(addr: i32, imm: i32) { - safe_read_write32(addr, &|x| rcl32(x, imm & 31)) -} -pub unsafe fn instr32_C1_2_reg(r1: i32, imm: i32) { - write_reg32(r1, rcl32(read_reg32(r1), imm & 31)); -} -pub unsafe fn instr32_C1_3_mem(addr: i32, imm: i32) { - safe_read_write32(addr, &|x| rcr32(x, imm & 31)) -} -pub unsafe fn instr32_C1_3_reg(r1: i32, imm: i32) { - write_reg32(r1, rcr32(read_reg32(r1), imm & 31)); -} -pub unsafe fn instr32_C1_4_mem(addr: i32, imm: i32) { - safe_read_write32(addr, &|x| shl32(x, imm & 31)) -} -pub unsafe fn instr32_C1_4_reg(r1: i32, imm: i32) { - write_reg32(r1, shl32(read_reg32(r1), imm & 31)); -} -pub unsafe fn instr32_C1_5_mem(addr: i32, imm: i32) { - safe_read_write32(addr, &|x| shr32(x, imm & 31)) -} -pub unsafe fn instr32_C1_5_reg(r1: i32, imm: i32) { - write_reg32(r1, shr32(read_reg32(r1), imm & 31)); -} -pub unsafe fn instr32_C1_6_mem(addr: i32, imm: i32) { - safe_read_write32(addr, &|x| shl32(x, imm & 31)) -} -pub unsafe fn instr32_C1_6_reg(r1: i32, imm: i32) { - write_reg32(r1, shl32(read_reg32(r1), imm & 31)); -} -pub unsafe fn instr32_C1_7_mem(addr: i32, imm: i32) { - safe_read_write32(addr, &|x| sar32(x, imm & 31)) -} -pub unsafe fn instr32_C1_7_reg(r1: i32, imm: i32) { - write_reg32(r1, sar32(read_reg32(r1), imm & 31)); -} - -pub unsafe fn instr16_C2(imm16: i32) { - // retn - let cs = get_seg_cs(); - *instruction_pointer = cs + return_on_pagefault!(pop16()); - dbg_assert!(*is_32 || get_real_eip() < 0x10000); - adjust_stack_reg(imm16); -} -pub unsafe fn instr32_C2(imm16: i32) { - // retn - let cs = get_seg_cs(); - let ip = return_on_pagefault!(pop32s()); - dbg_assert!(*is_32 || ip < 0x10000); - *instruction_pointer = cs + ip; - adjust_stack_reg(imm16); -} -pub unsafe fn instr16_C3() { - // retn - let cs = get_seg_cs(); - *instruction_pointer = cs + return_on_pagefault!(pop16()); -} -pub unsafe fn instr32_C3() { - // retn - let cs = get_seg_cs(); - let ip = return_on_pagefault!(pop32s()); - dbg_assert!(*is_32 || ip < 0x10000); - *instruction_pointer = cs + ip; -} - -#[no_mangle] -pub unsafe fn instr16_C4_reg(_unused1: i32, _unused2: i32) { trigger_ud(); } -#[no_mangle] -pub unsafe fn instr16_C4_mem(addr: i32, r: i32) { lss16(addr, r, ES); } -#[no_mangle] -pub unsafe fn instr32_C4_reg(_unused1: i32, _unused2: i32) { trigger_ud(); } -#[no_mangle] -pub unsafe fn instr32_C4_mem(addr: i32, r: i32) { lss32(addr, r, ES); } -#[no_mangle] -pub unsafe fn instr16_C5_reg(_unused1: i32, _unused2: i32) { trigger_ud(); } -#[no_mangle] -pub unsafe fn instr16_C5_mem(addr: i32, r: i32) { lss16(addr, r, DS); } -#[no_mangle] -pub unsafe fn instr32_C5_reg(_unused1: i32, _unused2: i32) { trigger_ud(); } -#[no_mangle] -pub unsafe fn instr32_C5_mem(addr: i32, r: i32) { lss32(addr, r, DS); } - -pub unsafe fn instr_C6_0_reg(r: i32, imm: i32) { write_reg8(r, imm); } -pub unsafe fn instr_C6_0_mem(addr: i32, imm: i32) { - return_on_pagefault!(safe_write8(addr, imm)); -} -pub unsafe fn instr16_C7_0_reg(r: i32, imm: i32) { write_reg16(r, imm); } -pub unsafe fn instr16_C7_0_mem(addr: i32, imm: i32) { - return_on_pagefault!(safe_write16(addr, imm)); -} -pub unsafe fn instr32_C7_0_reg(r: i32, imm: i32) { write_reg32(r, imm); } -pub unsafe fn instr32_C7_0_mem(addr: i32, imm: i32) { - return_on_pagefault!(safe_write32(addr, imm)); -} - -#[no_mangle] -pub unsafe fn instr16_C8(size: i32, nesting: i32) { enter16(size, nesting); } -#[no_mangle] -pub unsafe fn instr32_C8(size: i32, nesting: i32) { enter32(size, nesting); } - -pub unsafe fn instr16_C9() { - // leave - let old_vbp = if *stack_size_32 { read_reg32(EBP) } else { read_reg16(BP) }; - let new_bp = return_on_pagefault!(safe_read16(get_seg_ss() + old_vbp)); - set_stack_reg(old_vbp + 2); - write_reg16(BP, new_bp); -} -pub unsafe fn instr32_C9() { - let old_vbp = if *stack_size_32 { read_reg32(EBP) } else { read_reg16(BP) }; - let new_ebp = return_on_pagefault!(safe_read32s(get_seg_ss() + old_vbp)); - set_stack_reg(old_vbp + 4); - write_reg32(EBP, new_ebp); -} -#[no_mangle] -pub unsafe fn instr16_CA(imm16: i32) { - // retf - let ip = return_on_pagefault!(safe_read16(get_stack_pointer(0))); - let cs = return_on_pagefault!(safe_read16(get_stack_pointer(2))); - far_return(ip, cs, imm16, false); -} -#[no_mangle] -pub unsafe fn instr32_CA(imm16: i32) { - // retf - let ip = return_on_pagefault!(safe_read32s(get_stack_pointer(0))); - let cs = return_on_pagefault!(safe_read32s(get_stack_pointer(4))) & 0xFFFF; - far_return(ip, cs, imm16, true); - dbg_assert!(*is_32 || get_real_eip() < 0x10000); -} -#[no_mangle] -pub unsafe fn instr16_CB() { - // retf - let ip = return_on_pagefault!(safe_read16(get_stack_pointer(0))); - let cs = return_on_pagefault!(safe_read16(get_stack_pointer(2))); - far_return(ip, cs, 0, false); - dbg_assert!(*is_32 || get_real_eip() < 0x10000); -} -#[no_mangle] -pub unsafe fn instr32_CB() { - // retf - let ip = return_on_pagefault!(safe_read32s(get_stack_pointer(0))); - let cs = return_on_pagefault!(safe_read32s(get_stack_pointer(4))) & 0xFFFF; - far_return(ip, cs, 0, true); - dbg_assert!(*is_32 || get_real_eip() < 0x10000); -} -#[no_mangle] -pub unsafe fn instr_CC() { - // INT3 - // TODO: inhibit iopl checks - dbg_log!("INT3"); - call_interrupt_vector(3, true, None); -} -#[no_mangle] -pub unsafe fn instr_CD(imm8: i32) { - // INT - call_interrupt_vector(imm8, true, None); -} -#[no_mangle] -pub unsafe fn instr_CE() { - // INTO - dbg_log!("INTO"); - if getof() { - // TODO: inhibit iopl checks - call_interrupt_vector(CPU_EXCEPTION_OF, true, None); - }; -} -#[no_mangle] -pub unsafe fn instr16_CF() { - // iret - iret16(); -} -#[no_mangle] -pub unsafe fn instr32_CF() { iret32(); } - -pub unsafe fn instr_D0_0_mem(addr: i32) { safe_read_write8(addr, &|x| rol8(x, 1)) } -pub unsafe fn instr_D0_0_reg(r1: i32) { write_reg8(r1, rol8(read_reg8(r1), 1)); } -pub unsafe fn instr_D0_1_mem(addr: i32) { safe_read_write8(addr, &|x| ror8(x, 1)) } -pub unsafe fn instr_D0_1_reg(r1: i32) { write_reg8(r1, ror8(read_reg8(r1), 1)); } -pub unsafe fn instr_D0_2_mem(addr: i32) { safe_read_write8(addr, &|x| rcl8(x, 1)) } -pub unsafe fn instr_D0_2_reg(r1: i32) { write_reg8(r1, rcl8(read_reg8(r1), 1)); } -pub unsafe fn instr_D0_3_mem(addr: i32) { safe_read_write8(addr, &|x| rcr8(x, 1)) } -pub unsafe fn instr_D0_3_reg(r1: i32) { write_reg8(r1, rcr8(read_reg8(r1), 1)); } -pub unsafe fn instr_D0_4_mem(addr: i32) { safe_read_write8(addr, &|x| shl8(x, 1)) } -pub unsafe fn instr_D0_4_reg(r1: i32) { write_reg8(r1, shl8(read_reg8(r1), 1)); } -pub unsafe fn instr_D0_5_mem(addr: i32) { safe_read_write8(addr, &|x| shr8(x, 1)) } -pub unsafe fn instr_D0_5_reg(r1: i32) { write_reg8(r1, shr8(read_reg8(r1), 1)); } -pub unsafe fn instr_D0_6_mem(addr: i32) { safe_read_write8(addr, &|x| shl8(x, 1)) } -pub unsafe fn instr_D0_6_reg(r1: i32) { write_reg8(r1, shl8(read_reg8(r1), 1)); } -pub unsafe fn instr_D0_7_mem(addr: i32) { safe_read_write8(addr, &|x| sar8(x, 1)) } -pub unsafe fn instr_D0_7_reg(r1: i32) { write_reg8(r1, sar8(read_reg8(r1), 1)); } -pub unsafe fn instr16_D1_0_mem(addr: i32) { safe_read_write16(addr, &|x| rol16(x, 1)) } -pub unsafe fn instr16_D1_0_reg(r1: i32) { write_reg16(r1, rol16(read_reg16(r1), 1)); } -pub unsafe fn instr16_D1_1_mem(addr: i32) { safe_read_write16(addr, &|x| ror16(x, 1)) } -pub unsafe fn instr16_D1_1_reg(r1: i32) { write_reg16(r1, ror16(read_reg16(r1), 1)); } -pub unsafe fn instr16_D1_2_mem(addr: i32) { safe_read_write16(addr, &|x| rcl16(x, 1)) } -pub unsafe fn instr16_D1_2_reg(r1: i32) { write_reg16(r1, rcl16(read_reg16(r1), 1)); } -pub unsafe fn instr16_D1_3_mem(addr: i32) { safe_read_write16(addr, &|x| rcr16(x, 1)) } -pub unsafe fn instr16_D1_3_reg(r1: i32) { write_reg16(r1, rcr16(read_reg16(r1), 1)); } -pub unsafe fn instr16_D1_4_mem(addr: i32) { safe_read_write16(addr, &|x| shl16(x, 1)) } -pub unsafe fn instr16_D1_4_reg(r1: i32) { write_reg16(r1, shl16(read_reg16(r1), 1)); } -pub unsafe fn instr16_D1_5_mem(addr: i32) { safe_read_write16(addr, &|x| shr16(x, 1)) } -pub unsafe fn instr16_D1_5_reg(r1: i32) { write_reg16(r1, shr16(read_reg16(r1), 1)); } -pub unsafe fn instr16_D1_6_mem(addr: i32) { safe_read_write16(addr, &|x| shl16(x, 1)) } -pub unsafe fn instr16_D1_6_reg(r1: i32) { write_reg16(r1, shl16(read_reg16(r1), 1)); } -pub unsafe fn instr16_D1_7_mem(addr: i32) { safe_read_write16(addr, &|x| sar16(x, 1)) } -pub unsafe fn instr16_D1_7_reg(r1: i32) { write_reg16(r1, sar16(read_reg16(r1), 1)); } -pub unsafe fn instr32_D1_0_mem(addr: i32) { safe_read_write32(addr, &|x| rol32(x, 1)) } -pub unsafe fn instr32_D1_0_reg(r1: i32) { write_reg32(r1, rol32(read_reg32(r1), 1)); } -pub unsafe fn instr32_D1_1_mem(addr: i32) { safe_read_write32(addr, &|x| ror32(x, 1)) } -pub unsafe fn instr32_D1_1_reg(r1: i32) { write_reg32(r1, ror32(read_reg32(r1), 1)); } -pub unsafe fn instr32_D1_2_mem(addr: i32) { safe_read_write32(addr, &|x| rcl32(x, 1)) } -pub unsafe fn instr32_D1_2_reg(r1: i32) { write_reg32(r1, rcl32(read_reg32(r1), 1)); } -pub unsafe fn instr32_D1_3_mem(addr: i32) { safe_read_write32(addr, &|x| rcr32(x, 1)) } -pub unsafe fn instr32_D1_3_reg(r1: i32) { write_reg32(r1, rcr32(read_reg32(r1), 1)); } -pub unsafe fn instr32_D1_4_mem(addr: i32) { safe_read_write32(addr, &|x| shl32(x, 1)) } -pub unsafe fn instr32_D1_4_reg(r1: i32) { write_reg32(r1, shl32(read_reg32(r1), 1)); } -pub unsafe fn instr32_D1_5_mem(addr: i32) { safe_read_write32(addr, &|x| shr32(x, 1)) } -pub unsafe fn instr32_D1_5_reg(r1: i32) { write_reg32(r1, shr32(read_reg32(r1), 1)); } -pub unsafe fn instr32_D1_6_mem(addr: i32) { safe_read_write32(addr, &|x| shl32(x, 1)) } -pub unsafe fn instr32_D1_6_reg(r1: i32) { write_reg32(r1, shl32(read_reg32(r1), 1)); } -pub unsafe fn instr32_D1_7_mem(addr: i32) { safe_read_write32(addr, &|x| sar32(x, 1)) } -pub unsafe fn instr32_D1_7_reg(r1: i32) { write_reg32(r1, sar32(read_reg32(r1), 1)); } -pub unsafe fn instr_D2_0_mem(addr: i32) { safe_read_write8(addr, &|x| rol8(x, read_reg8(CL) & 31)) } -pub unsafe fn instr_D2_0_reg(r1: i32) { write_reg8(r1, rol8(read_reg8(r1), read_reg8(CL) & 31)); } -pub unsafe fn instr_D2_1_mem(addr: i32) { safe_read_write8(addr, &|x| ror8(x, read_reg8(CL) & 31)) } -pub unsafe fn instr_D2_1_reg(r1: i32) { write_reg8(r1, ror8(read_reg8(r1), read_reg8(CL) & 31)); } -pub unsafe fn instr_D2_2_mem(addr: i32) { safe_read_write8(addr, &|x| rcl8(x, read_reg8(CL) & 31)) } -pub unsafe fn instr_D2_2_reg(r1: i32) { write_reg8(r1, rcl8(read_reg8(r1), read_reg8(CL) & 31)); } -pub unsafe fn instr_D2_3_mem(addr: i32) { safe_read_write8(addr, &|x| rcr8(x, read_reg8(CL) & 31)) } -pub unsafe fn instr_D2_3_reg(r1: i32) { write_reg8(r1, rcr8(read_reg8(r1), read_reg8(CL) & 31)); } -pub unsafe fn instr_D2_4_mem(addr: i32) { safe_read_write8(addr, &|x| shl8(x, read_reg8(CL) & 31)) } -pub unsafe fn instr_D2_4_reg(r1: i32) { write_reg8(r1, shl8(read_reg8(r1), read_reg8(CL) & 31)); } -pub unsafe fn instr_D2_5_mem(addr: i32) { safe_read_write8(addr, &|x| shr8(x, read_reg8(CL) & 31)) } -pub unsafe fn instr_D2_5_reg(r1: i32) { write_reg8(r1, shr8(read_reg8(r1), read_reg8(CL) & 31)); } -pub unsafe fn instr_D2_6_mem(addr: i32) { safe_read_write8(addr, &|x| shl8(x, read_reg8(CL) & 31)) } -pub unsafe fn instr_D2_6_reg(r1: i32) { write_reg8(r1, shl8(read_reg8(r1), read_reg8(CL) & 31)); } -pub unsafe fn instr_D2_7_mem(addr: i32) { safe_read_write8(addr, &|x| sar8(x, read_reg8(CL) & 31)) } -pub unsafe fn instr_D2_7_reg(r1: i32) { write_reg8(r1, sar8(read_reg8(r1), read_reg8(CL) & 31)); } -pub unsafe fn instr16_D3_0_mem(addr: i32) { - safe_read_write16(addr, &|x| rol16(x, read_reg8(CL) & 31)) -} -pub unsafe fn instr16_D3_0_reg(r1: i32) { - write_reg16(r1, rol16(read_reg16(r1), read_reg8(CL) & 31)); -} -pub unsafe fn instr16_D3_1_mem(addr: i32) { - safe_read_write16(addr, &|x| ror16(x, read_reg8(CL) & 31)) -} -pub unsafe fn instr16_D3_1_reg(r1: i32) { - write_reg16(r1, ror16(read_reg16(r1), read_reg8(CL) & 31)); -} -pub unsafe fn instr16_D3_2_mem(addr: i32) { - safe_read_write16(addr, &|x| rcl16(x, read_reg8(CL) & 31)) -} -pub unsafe fn instr16_D3_2_reg(r1: i32) { - write_reg16(r1, rcl16(read_reg16(r1), read_reg8(CL) & 31)); -} -pub unsafe fn instr16_D3_3_mem(addr: i32) { - safe_read_write16(addr, &|x| rcr16(x, read_reg8(CL) & 31)) -} -pub unsafe fn instr16_D3_3_reg(r1: i32) { - write_reg16(r1, rcr16(read_reg16(r1), read_reg8(CL) & 31)); -} -pub unsafe fn instr16_D3_4_mem(addr: i32) { - safe_read_write16(addr, &|x| shl16(x, read_reg8(CL) & 31)) -} -pub unsafe fn instr16_D3_4_reg(r1: i32) { - write_reg16(r1, shl16(read_reg16(r1), read_reg8(CL) & 31)); -} -pub unsafe fn instr16_D3_5_mem(addr: i32) { - safe_read_write16(addr, &|x| shr16(x, read_reg8(CL) & 31)) -} -pub unsafe fn instr16_D3_5_reg(r1: i32) { - write_reg16(r1, shr16(read_reg16(r1), read_reg8(CL) & 31)); -} -pub unsafe fn instr16_D3_6_mem(addr: i32) { - safe_read_write16(addr, &|x| shl16(x, read_reg8(CL) & 31)) -} -pub unsafe fn instr16_D3_6_reg(r1: i32) { - write_reg16(r1, shl16(read_reg16(r1), read_reg8(CL) & 31)); -} -pub unsafe fn instr16_D3_7_mem(addr: i32) { - safe_read_write16(addr, &|x| sar16(x, read_reg8(CL) & 31)) -} -pub unsafe fn instr16_D3_7_reg(r1: i32) { - write_reg16(r1, sar16(read_reg16(r1), read_reg8(CL) & 31)); -} -pub unsafe fn instr32_D3_0_mem(addr: i32) { - safe_read_write32(addr, &|x| rol32(x, read_reg8(CL) & 31)) -} -pub unsafe fn instr32_D3_0_reg(r1: i32) { - write_reg32(r1, rol32(read_reg32(r1), read_reg8(CL) & 31)); -} -pub unsafe fn instr32_D3_1_mem(addr: i32) { - safe_read_write32(addr, &|x| ror32(x, read_reg8(CL) & 31)) -} -pub unsafe fn instr32_D3_1_reg(r1: i32) { - write_reg32(r1, ror32(read_reg32(r1), read_reg8(CL) & 31)); -} -pub unsafe fn instr32_D3_2_mem(addr: i32) { - safe_read_write32(addr, &|x| rcl32(x, read_reg8(CL) & 31)) -} -pub unsafe fn instr32_D3_2_reg(r1: i32) { - write_reg32(r1, rcl32(read_reg32(r1), read_reg8(CL) & 31)); -} -pub unsafe fn instr32_D3_3_mem(addr: i32) { - safe_read_write32(addr, &|x| rcr32(x, read_reg8(CL) & 31)) -} -pub unsafe fn instr32_D3_3_reg(r1: i32) { - write_reg32(r1, rcr32(read_reg32(r1), read_reg8(CL) & 31)); -} -pub unsafe fn instr32_D3_4_mem(addr: i32) { - safe_read_write32(addr, &|x| shl32(x, read_reg8(CL) & 31)) -} -pub unsafe fn instr32_D3_4_reg(r1: i32) { - write_reg32(r1, shl32(read_reg32(r1), read_reg8(CL) & 31)); -} -pub unsafe fn instr32_D3_5_mem(addr: i32) { - safe_read_write32(addr, &|x| shr32(x, read_reg8(CL) & 31)) -} -pub unsafe fn instr32_D3_5_reg(r1: i32) { - write_reg32(r1, shr32(read_reg32(r1), read_reg8(CL) & 31)); -} -pub unsafe fn instr32_D3_6_mem(addr: i32) { - safe_read_write32(addr, &|x| shl32(x, read_reg8(CL) & 31)) -} -pub unsafe fn instr32_D3_6_reg(r1: i32) { - write_reg32(r1, shl32(read_reg32(r1), read_reg8(CL) & 31)); -} -pub unsafe fn instr32_D3_7_mem(addr: i32) { - safe_read_write32(addr, &|x| sar32(x, read_reg8(CL) & 31)) -} -pub unsafe fn instr32_D3_7_reg(r1: i32) { - write_reg32(r1, sar32(read_reg32(r1), read_reg8(CL) & 31)); -} -#[no_mangle] -pub unsafe fn instr_D4(arg: i32) { bcd_aam(arg); } -#[no_mangle] -pub unsafe fn instr_D5(arg: i32) { bcd_aad(arg); } -#[no_mangle] -pub unsafe fn instr_D6() { - // salc - write_reg8(AL, -(getcf() as i32)); -} -pub unsafe fn instr_D7() { - // xlat - dbg_assert!(!in_jit); - if is_asize_32() { - write_reg8( - AL, - return_on_pagefault!(safe_read8( - return_on_pagefault!(get_seg_prefix(DS)) + read_reg32(EBX) + read_reg8(AL), - )), - ) + const check_prefixes = encoding.sse ? "(::prefix::PREFIX_66 | ::prefix::PREFIX_F2 | ::prefix::PREFIX_F3)" : "(::prefix::PREFIX_F2 | ::prefix::PREFIX_F3)"; + + const else_block = { + body: [].concat( + "dbg_assert!((prefixes_ & " + check_prefixes + ") == 0);", + gen_instruction_body_after_prefix(no_prefix, size) + ) + }; + + return [].concat( + "let prefixes_ = *prefixes;", + code, + { + type: "if-else", + if_blocks, + else_block, + } + ); } else { - write_reg8( - AL, - return_on_pagefault!(safe_read8( - return_on_pagefault!(get_seg_prefix(DS)) - + (read_reg16(BX) + read_reg8(AL) & 0xFFFF), - )), - ) - }; + return [].concat( + code, + gen_instruction_body_after_prefix(encodings, size) + ); + } } -pub unsafe fn instr_D8_0_mem(addr: i32) { fpu_fadd(0, return_on_pagefault!(fpu_load_m32(addr))); } -pub unsafe fn instr_D8_0_reg(r: i32) { fpu_fadd(0, fpu_get_sti(r)); } -pub unsafe fn instr_D8_1_mem(addr: i32) { fpu_fmul(0, return_on_pagefault!(fpu_load_m32(addr))); } -pub unsafe fn instr_D8_1_reg(r: i32) { fpu_fmul(0, fpu_get_sti(r)); } -pub unsafe fn instr_D8_2_mem(addr: i32) { fpu_fcom(return_on_pagefault!(fpu_load_m32(addr))); } -pub unsafe fn instr_D8_2_reg(r: i32) { fpu_fcom(fpu_get_sti(r)); } -pub unsafe fn instr_D8_3_mem(addr: i32) { fpu_fcomp(return_on_pagefault!(fpu_load_m32(addr))); } -pub unsafe fn instr_D8_3_reg(r: i32) { fpu_fcomp(fpu_get_sti(r)); } -pub unsafe fn instr_D8_4_mem(addr: i32) { fpu_fsub(0, return_on_pagefault!(fpu_load_m32(addr))); } -pub unsafe fn instr_D8_4_reg(r: i32) { fpu_fsub(0, fpu_get_sti(r)); } -pub unsafe fn instr_D8_5_mem(addr: i32) { fpu_fsubr(0, return_on_pagefault!(fpu_load_m32(addr))); } -pub unsafe fn instr_D8_5_reg(r: i32) { fpu_fsubr(0, fpu_get_sti(r)); } -pub unsafe fn instr_D8_6_mem(addr: i32) { fpu_fdiv(0, return_on_pagefault!(fpu_load_m32(addr))); } -pub unsafe fn instr_D8_6_reg(r: i32) { fpu_fdiv(0, fpu_get_sti(r)); } -pub unsafe fn instr_D8_7_mem(addr: i32) { fpu_fdivr(0, return_on_pagefault!(fpu_load_m32(addr))); } -pub unsafe fn instr_D8_7_reg(r: i32) { fpu_fdivr(0, fpu_get_sti(r)); } -pub unsafe fn instr16_D9_0_mem(addr: i32) { fpu_fldm32(addr); } -pub unsafe fn instr16_D9_0_reg(r: i32) { fpu_push(fpu_get_sti(r)); } -pub unsafe fn instr16_D9_1_mem(_addr: i32) { - dbg_log!("d9/1"); - trigger_ud(); -} -pub unsafe fn instr16_D9_1_reg(r: i32) { fpu_fxch(r); } -pub unsafe fn instr16_D9_2_mem(addr: i32) { fpu_fstm32(addr); } -pub unsafe fn instr16_D9_2_reg(r: i32) { - if r != 0 { - trigger_ud(); - }; -} -pub unsafe fn instr16_D9_3_mem(addr: i32) { fpu_fstm32p(addr); } -pub unsafe fn instr16_D9_3_reg(r: i32) { fpu_fstp(r) } -#[no_mangle] -pub unsafe fn instr16_D9_4_mem(addr: i32) { fpu_fldenv16(addr); } -pub unsafe fn instr32_D9_4_mem(addr: i32) { fpu_fldenv32(addr); } -#[no_mangle] -pub unsafe fn instr16_D9_4_reg(r: i32) { - match r { - 0 => fpu_fchs(), - 1 => fpu_fabs(), - 4 => fpu_ftst(), - 5 => fpu_fxam(), - _ => { - dbg_log!("{:x}", r); - trigger_ud(); - }, - }; -} -#[no_mangle] -pub unsafe fn instr16_D9_5_mem(addr: i32) { fpu_fldcw(addr); } -#[no_mangle] -pub unsafe fn instr16_D9_5_reg(r: i32) { - // fld1/fldl2t/fldl2e/fldpi/fldlg2/fldln2/fldz - match r { - 0 => fpu_push(F80::ONE), - 1 => fpu_push(F80::LN_10 / F80::LN_2), - 2 => fpu_push(F80::LOG2_E), - 3 => fpu_push(F80::PI), - 4 => fpu_push(F80::LN_2 / F80::LN_10), - 5 => fpu_push(F80::LN_2), - 6 => fpu_push(F80::ZERO), - 7 => { - dbg_log!("d9/5/7"); - trigger_ud(); - }, - _ => {}, - }; -} -pub unsafe fn instr16_D9_6_mem(addr: i32) { fpu_fstenv16(addr); } -pub unsafe fn instr32_D9_6_mem(addr: i32) { fpu_fstenv32(addr); } -#[no_mangle] -pub unsafe fn instr16_D9_6_reg(r: i32) { - match r { - 0 => fpu_f2xm1(), - 1 => fpu_fyl2x(), - 2 => fpu_fptan(), - 3 => fpu_fpatan(), - 4 => fpu_fxtract(), - 5 => fpu_fprem(true), // fprem1 - 6 => fpu_fdecstp(), - 7 => fpu_fincstp(), - _ => { - dbg_assert!(false); - }, - }; -} -pub unsafe fn instr16_D9_7_mem(addr: i32) { fpu_fstcw(addr); } -#[no_mangle] -pub unsafe fn instr16_D9_7_reg(r: i32) { - match r { - 0 => fpu_fprem(false), - 1 => fpu_fyl2xp1(), - 2 => fpu_fsqrt(), - 3 => fpu_fsincos(), - 4 => fpu_frndint(), - 5 => fpu_fscale(), - 6 => fpu_fsin(), - 7 => fpu_fcos(), - _ => { - dbg_assert!(false); - }, - }; -} +function gen_instruction_body_after_prefix(encodings, size) +{ + const encoding = encodings[0]; -pub unsafe fn instr32_D9_0_reg(r: i32) { instr16_D9_0_reg(r) } -pub unsafe fn instr32_D9_1_reg(r: i32) { instr16_D9_1_reg(r) } -pub unsafe fn instr32_D9_2_reg(r: i32) { instr16_D9_2_reg(r) } -pub unsafe fn instr32_D9_3_reg(r: i32) { instr16_D9_3_reg(r) } -pub unsafe fn instr32_D9_4_reg(r: i32) { instr16_D9_4_reg(r) } -pub unsafe fn instr32_D9_5_reg(r: i32) { instr16_D9_5_reg(r) } -pub unsafe fn instr32_D9_6_reg(r: i32) { instr16_D9_6_reg(r) } -pub unsafe fn instr32_D9_7_reg(r: i32) { instr16_D9_7_reg(r) } - -pub unsafe fn instr32_D9_0_mem(r: i32) { instr16_D9_0_mem(r) } -pub unsafe fn instr32_D9_1_mem(r: i32) { instr16_D9_1_mem(r) } -pub unsafe fn instr32_D9_2_mem(r: i32) { instr16_D9_2_mem(r) } -pub unsafe fn instr32_D9_3_mem(r: i32) { instr16_D9_3_mem(r) } -pub unsafe fn instr32_D9_5_mem(r: i32) { instr16_D9_5_mem(r) } -pub unsafe fn instr32_D9_7_mem(r: i32) { instr16_D9_7_mem(r) } - -pub unsafe fn instr_DA_0_mem(addr: i32) { fpu_fadd(0, return_on_pagefault!(fpu_load_i32(addr))); } -pub unsafe fn instr_DA_1_mem(addr: i32) { fpu_fmul(0, return_on_pagefault!(fpu_load_i32(addr))); } -pub unsafe fn instr_DA_2_mem(addr: i32) { fpu_fcom(return_on_pagefault!(fpu_load_i32(addr))); } -pub unsafe fn instr_DA_3_mem(addr: i32) { fpu_fcomp(return_on_pagefault!(fpu_load_i32(addr))); } -pub unsafe fn instr_DA_4_mem(addr: i32) { fpu_fsub(0, return_on_pagefault!(fpu_load_i32(addr))); } -pub unsafe fn instr_DA_5_mem(addr: i32) { fpu_fsubr(0, return_on_pagefault!(fpu_load_i32(addr))); } -pub unsafe fn instr_DA_6_mem(addr: i32) { fpu_fdiv(0, return_on_pagefault!(fpu_load_i32(addr))); } -pub unsafe fn instr_DA_7_mem(addr: i32) { fpu_fdivr(0, return_on_pagefault!(fpu_load_i32(addr))); } -#[no_mangle] -pub unsafe fn instr_DA_0_reg(r: i32) { fpu_fcmovcc(test_b(), r); } -#[no_mangle] -pub unsafe fn instr_DA_1_reg(r: i32) { fpu_fcmovcc(test_z(), r); } -#[no_mangle] -pub unsafe fn instr_DA_2_reg(r: i32) { fpu_fcmovcc(test_be(), r); } -#[no_mangle] -pub unsafe fn instr_DA_3_reg(r: i32) { fpu_fcmovcc(test_p(), r); } -pub unsafe fn instr_DA_4_reg(_r: i32) { trigger_ud(); } -pub unsafe fn instr_DA_5_reg(r: i32) { - if r == 1 { - fpu_fucompp(); - } - else { - trigger_ud(); - }; -} -pub unsafe fn instr_DA_6_reg(_r: i32) { trigger_ud(); } -pub unsafe fn instr_DA_7_reg(_r: i32) { trigger_ud(); } -pub unsafe fn instr_DB_0_mem(addr: i32) { fpu_fildm32(addr); } -#[no_mangle] -pub unsafe fn instr_DB_2_mem(addr: i32) { fpu_fistm32(addr); } -pub unsafe fn instr_DB_3_mem(addr: i32) { fpu_fistm32p(addr); } -#[no_mangle] -pub unsafe fn instr_DB_4_mem(_addr: i32) { trigger_ud(); } -pub unsafe fn instr_DB_5_mem(addr: i32) { fpu_fldm80(addr); } -pub unsafe fn instr_DB_6_mem(_addr: i32) { trigger_ud(); } -#[no_mangle] -pub unsafe fn instr_DB_7_mem(addr: i32) { fpu_fst80p(addr); } -#[no_mangle] -pub unsafe fn instr_DB_0_reg(r: i32) { fpu_fcmovcc(!test_b(), r); } -#[no_mangle] -pub unsafe fn instr_DB_1_reg(r: i32) { fpu_fcmovcc(!test_z(), r); } -#[no_mangle] -pub unsafe fn instr_DB_2_reg(r: i32) { fpu_fcmovcc(!test_be(), r); } -#[no_mangle] -pub unsafe fn instr_DB_3_reg(r: i32) { fpu_fcmovcc(!test_p(), r); } -#[no_mangle] -pub unsafe fn instr_DB_4_reg(r: i32) { - if r == 3 { - fpu_finit(); - } - else if r == 4 || r == 1 || r == 0 { - // fsetpm, fdisi, fneni; treated as nop - } - else if r == 2 { - fpu_fclex(); - } - else { - trigger_ud(); - }; -} -pub unsafe fn instr_DB_5_reg(r: i32) { fpu_fucomi(r); } -pub unsafe fn instr_DB_6_reg(r: i32) { fpu_fcomi(r); } -#[no_mangle] -pub unsafe fn instr_DB_7_reg(_r: i32) { trigger_ud(); } - -pub unsafe fn instr_DC_0_mem(addr: i32) { fpu_fadd(0, return_on_pagefault!(fpu_load_m64(addr))); } -pub unsafe fn instr_DC_1_mem(addr: i32) { fpu_fmul(0, return_on_pagefault!(fpu_load_m64(addr))); } -pub unsafe fn instr_DC_2_mem(addr: i32) { fpu_fcom(return_on_pagefault!(fpu_load_m64(addr))); } -pub unsafe fn instr_DC_3_mem(addr: i32) { fpu_fcomp(return_on_pagefault!(fpu_load_m64(addr))); } -pub unsafe fn instr_DC_4_mem(addr: i32) { fpu_fsub(0, return_on_pagefault!(fpu_load_m64(addr))); } -pub unsafe fn instr_DC_5_mem(addr: i32) { fpu_fsubr(0, return_on_pagefault!(fpu_load_m64(addr))); } -pub unsafe fn instr_DC_6_mem(addr: i32) { fpu_fdiv(0, return_on_pagefault!(fpu_load_m64(addr))); } -pub unsafe fn instr_DC_7_mem(addr: i32) { fpu_fdivr(0, return_on_pagefault!(fpu_load_m64(addr))); } -pub unsafe fn instr_DC_0_reg(r: i32) { fpu_fadd(r, fpu_get_sti(r)); } -pub unsafe fn instr_DC_1_reg(r: i32) { fpu_fmul(r, fpu_get_sti(r)); } -pub unsafe fn instr_DC_2_reg(r: i32) { fpu_fcom(fpu_get_sti(r)); } -pub unsafe fn instr_DC_3_reg(r: i32) { fpu_fcomp(fpu_get_sti(r)); } -pub unsafe fn instr_DC_4_reg(r: i32) { fpu_fsub(r, fpu_get_sti(r)); } -pub unsafe fn instr_DC_5_reg(r: i32) { fpu_fsubr(r, fpu_get_sti(r)); } -pub unsafe fn instr_DC_6_reg(r: i32) { fpu_fdiv(r, fpu_get_sti(r)); } -pub unsafe fn instr_DC_7_reg(r: i32) { fpu_fdivr(r, fpu_get_sti(r)); } - -pub unsafe fn instr16_DD_0_mem(addr: i32) { fpu_fldm64(addr); } -#[no_mangle] -pub unsafe fn instr16_DD_2_mem(addr: i32) { fpu_fstm64(addr); } -pub unsafe fn instr16_DD_3_mem(addr: i32) { fpu_fstm64p(addr); } -#[no_mangle] -pub unsafe fn instr16_DD_4_mem(addr: i32) { fpu_frstor16(addr); } -#[no_mangle] -pub unsafe fn instr32_DD_4_mem(addr: i32) { fpu_frstor32(addr); } -pub unsafe fn instr16_DD_5_mem(_addr: i32) { - dbg_log!("dd/5"); - trigger_ud(); -} -#[no_mangle] -pub unsafe fn instr16_DD_6_mem(addr: i32) { fpu_fsave16(addr); } -#[no_mangle] -pub unsafe fn instr32_DD_6_mem(addr: i32) { fpu_fsave32(addr); } -#[no_mangle] -pub unsafe fn instr16_DD_7_mem(addr: i32) { fpu_fnstsw_mem(addr); } -pub unsafe fn instr16_DD_0_reg(r: i32) { fpu_ffree(r); } -#[no_mangle] -pub unsafe fn instr16_DD_1_reg(r: i32) { fpu_fxch(r) } -pub unsafe fn instr16_DD_2_reg(r: i32) { fpu_fst(r); } -pub unsafe fn instr16_DD_3_reg(r: i32) { fpu_fstp(r); } -#[no_mangle] -pub unsafe fn instr16_DD_4_reg(r: i32) { fpu_fucom(r); } -pub unsafe fn instr16_DD_5_reg(r: i32) { fpu_fucomp(r); } -#[no_mangle] -pub unsafe fn instr16_DD_6_reg(_r: i32) { trigger_ud(); } -#[no_mangle] -pub unsafe fn instr16_DD_7_reg(_r: i32) { trigger_ud(); } - -pub unsafe fn instr32_DD_0_reg(r: i32) { instr16_DD_0_reg(r) } -#[no_mangle] -pub unsafe fn instr32_DD_1_reg(r: i32) { instr16_DD_1_reg(r) } -pub unsafe fn instr32_DD_2_reg(r: i32) { instr16_DD_2_reg(r) } -pub unsafe fn instr32_DD_3_reg(r: i32) { instr16_DD_3_reg(r) } -#[no_mangle] -pub unsafe fn instr32_DD_4_reg(r: i32) { instr16_DD_4_reg(r) } -pub unsafe fn instr32_DD_5_reg(r: i32) { instr16_DD_5_reg(r) } -#[no_mangle] -pub unsafe fn instr32_DD_6_reg(r: i32) { instr16_DD_6_reg(r) } -#[no_mangle] -pub unsafe fn instr32_DD_7_reg(r: i32) { instr16_DD_7_reg(r) } - -pub unsafe fn instr32_DD_0_mem(r: i32) { instr16_DD_0_mem(r) } -#[no_mangle] -pub unsafe fn instr32_DD_1_mem(r: i32) { instr16_DD_1_mem(r) } -pub unsafe fn instr32_DD_2_mem(r: i32) { instr16_DD_2_mem(r) } -pub unsafe fn instr32_DD_3_mem(r: i32) { instr16_DD_3_mem(r) } -pub unsafe fn instr32_DD_5_mem(r: i32) { instr16_DD_5_mem(r) } -#[no_mangle] -pub unsafe fn instr32_DD_7_mem(r: i32) { instr16_DD_7_mem(r) } - -#[no_mangle] -pub unsafe fn instr_DE_0_mem(addr: i32) { fpu_fadd(0, return_on_pagefault!(fpu_load_i16(addr))); } -#[no_mangle] -pub unsafe fn instr_DE_1_mem(addr: i32) { fpu_fmul(0, return_on_pagefault!(fpu_load_i16(addr))); } -#[no_mangle] -pub unsafe fn instr_DE_2_mem(addr: i32) { fpu_fcom(return_on_pagefault!(fpu_load_i16(addr))); } -#[no_mangle] -pub unsafe fn instr_DE_3_mem(addr: i32) { fpu_fcomp(return_on_pagefault!(fpu_load_i16(addr))); } -#[no_mangle] -pub unsafe fn instr_DE_4_mem(addr: i32) { fpu_fsub(0, return_on_pagefault!(fpu_load_i16(addr))); } -#[no_mangle] -pub unsafe fn instr_DE_5_mem(addr: i32) { fpu_fsubr(0, return_on_pagefault!(fpu_load_i16(addr))); } -#[no_mangle] -pub unsafe fn instr_DE_6_mem(addr: i32) { fpu_fdiv(0, return_on_pagefault!(fpu_load_i16(addr))); } -#[no_mangle] -pub unsafe fn instr_DE_7_mem(addr: i32) { fpu_fdivr(0, return_on_pagefault!(fpu_load_i16(addr))); } - -#[no_mangle] -pub unsafe fn instr_DE_0_reg(r: i32) { - fpu_fadd(r, fpu_get_sti(r)); - fpu_pop(); -} -pub unsafe fn instr_DE_1_reg(r: i32) { - fpu_fmul(r, fpu_get_sti(r)); - fpu_pop(); -} -pub unsafe fn instr_DE_2_reg(r: i32) { - fpu_fcom(fpu_get_sti(r)); - fpu_pop(); -} -pub unsafe fn instr_DE_3_reg(r: i32) { - if r == 1 { - fpu_fcomp(fpu_get_sti(r)); - fpu_pop(); - } - else { - trigger_ud(); - } -} -pub unsafe fn instr_DE_4_reg(r: i32) { - fpu_fsub(r, fpu_get_sti(r)); - fpu_pop(); -} -pub unsafe fn instr_DE_5_reg(r: i32) { - fpu_fsubr(r, fpu_get_sti(r)); - fpu_pop(); -} -pub unsafe fn instr_DE_6_reg(r: i32) { - fpu_fdiv(r, fpu_get_sti(r)); - fpu_pop(); -} -pub unsafe fn instr_DE_7_reg(r: i32) { - fpu_fdivr(r, fpu_get_sti(r)); - fpu_pop(); -} -#[no_mangle] -pub unsafe fn instr_DF(source: reg128, r: i32) { - // haddps xmm, xmm/mem128 - let destination = read_xmm128s(r); - let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], - ], - }; - write_xmm_reg128(r, result); -} -pub unsafe fn instr_DF_reg(r1: i32, r2: i32) { instr_DF(read_xmm128s(r1), r2); } -pub unsafe fn instr_DF_mem(addr: i32, r: i32) { - instr_DF(return_on_pagefault!(safe_read128s(addr)), r); -} -#[no_mangle] -pub unsafe fn instr_DD(source: reg128, r: i32) { - // haddps xmm, xmm/mem128 - let destination = read_xmm128s(r); - let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], - ], - }; - write_xmm_reg128(r, result); -} -#[no_mangle] -pub unsafe fn instr_DF_1_reg(r: i32) { fpu_fxch(r) } -pub unsafe fn instr_DF_2_reg(r: i32) { fpu_fstp(r); } -pub unsafe fn instr_DF_3_reg(r: i32) { fpu_fstp(r); } -pub unsafe fn instr_DF_4_reg(r: i32) { - if r == 0 { - fpu_fnstsw_reg(); + if(encoding.fixed_g !== undefined) + { + assert(encoding.e); + + // instruction with modrm byte where the middle 3 bits encode the instruction + + // group by opcode without prefix plus middle bits of modrm byte + let cases = encodings.reduce((cases_by_opcode, case_) => { + assert(typeof case_.fixed_g === "number"); + cases_by_opcode[case_.opcode & 0xFFFF | case_.fixed_g << 16] = case_; + return cases_by_opcode; + }, Object.create(null)); + cases = Object.values(cases).sort((e1, e2) => e1.fixed_g - e2.fixed_g); + + return [ + { + type: "switch", + condition: "modrm_byte >> 3 & 7", + cases: cases.map(case_ => { + const fixed_g = case_.fixed_g; + const body = gen_instruction_body_after_fixed_g(case_, size); + + return { + conditions: [fixed_g], + body, + }; + }), + + default_case: { + body: [ + `if DEBUG { panic!("Bad instruction at {:x}", *instruction_pointer); }`, + "trigger_ud();", + ], + } + }, + ]; } else { - trigger_ud(); - }; -} -pub unsafe fn instr_DD_reg(r1: i32, r2: i32) { instr_DD(read_xmm128s(r1), r2); } -pub unsafe fn instr_DD_mem(addr: i32, r: i32) { - instr_DD(return_on_pagefault!(safe_read128s(addr)), r); -} -pub unsafe fn instr_DF_0_mem(addr: i32) { fpu_fildm16(addr) } -pub unsafe fn instr_DF_1_mem(addr: i32) { fpu_fxchm16(addr) } -pub unsafe fn instr_DF_2_mem(addr: i32) { fpu_fistm16(addr); } -pub unsafe fn instr_DF_3_mem(addr: i32) { fpu_fistm16p(addr); } -pub unsafe fn instr_DF_4_mem(_addr: i32) { - dbg_log!("fbld"); - fpu_unimpl(); -} -pub unsafe fn instr_DF_5_mem(addr: i32) { fpu_fildm64(addr); } -pub unsafe fn instr_DF_6_mem(addr: i32) { fpu_fbstp(addr); } -pub unsafe fn instr_DF_7_mem(addr: i32) { fpu_fistm64p(addr); } -#[no_mangle] -pub unsafe fn instr_DF_0_reg(r: i32) { - fpu_ffree(r); - fpu_pop(); -} -pub unsafe fn instr_DF_5_reg(r: i32) { fpu_fucomip(r); } -pub unsafe fn instr_DF_6_reg(r: i32) { fpu_fcomip(r); } -pub unsafe fn instr_DF_7_reg(_r: i32) { trigger_ud(); } - -pub unsafe fn instr16_E0(imm8s: i32) { loopne16(imm8s); } -pub unsafe fn instr16_E1(imm8s: i32) { loope16(imm8s); } -pub unsafe fn instr16_E2(imm8s: i32) { loop16(imm8s); } -pub unsafe fn instr16_E3(imm8s: i32) { jcxz16(imm8s); } -pub unsafe fn instr32_E0(imm8s: i32) { loopne32(imm8s); } -pub unsafe fn instr32_E1(imm8s: i32) { loope32(imm8s); } -pub unsafe fn instr32_E2(imm8s: i32) { loop32(imm8s); } -pub unsafe fn instr32_E3(imm8s: i32) { jcxz32(imm8s); } - -#[no_mangle] -pub unsafe fn instr_E4(port: i32) { - if test_privileges_for_io(port, 1) { - write_reg8(AL, io_port_read8(port)); - } -} -#[no_mangle] -pub unsafe fn instr16_E5(port: i32) { - if test_privileges_for_io(port, 2) { - write_reg16(AX, io_port_read16(port)); - } -} -#[no_mangle] -pub unsafe fn instr32_E5(port: i32) { - if test_privileges_for_io(port, 4) { - write_reg32(EAX, io_port_read32(port)); - } -} -#[no_mangle] -pub unsafe fn instr_E6(port: i32) { - if test_privileges_for_io(port, 1) { - io_port_write8(port, read_reg8(AL)); - } -} -#[no_mangle] -pub unsafe fn instr16_E7(port: i32) { - if test_privileges_for_io(port, 2) { - io_port_write16(port, read_reg16(AX)); - } -} -#[no_mangle] -pub unsafe fn instr32_E7(port: i32) { - if test_privileges_for_io(port, 4) { - io_port_write32(port, read_reg32(EAX)); + assert(encodings.length === 1); + return gen_instruction_body_after_fixed_g(encodings[0], size); } } -pub unsafe fn instr16_E8(imm16: i32) { - // call - return_on_pagefault!(push16(get_real_eip())); - jmp_rel16(imm16); -} -pub unsafe fn instr32_E8(imm32s: i32) { - // call - return_on_pagefault!(push32(get_real_eip())); - *instruction_pointer = *instruction_pointer + imm32s; - dbg_assert!(*is_32 || get_real_eip() < 0x10000); -} -pub unsafe fn instr16_E9(imm16: i32) { - // jmp - jmp_rel16(imm16); -} -pub unsafe fn instr32_E9(imm32s: i32) { - // jmp - *instruction_pointer = *instruction_pointer + imm32s; - dbg_assert!(*is_32 || get_real_eip() < 0x10000); -} +function gen_instruction_body_after_fixed_g(encoding, size) +{ + const instruction_prefix = []; + const instruction_postfix = + (encoding.block_boundary && !encoding.no_block_boundary_in_interpreted) || + (!encoding.custom && encoding.e) ? + ["after_block_boundary();"] : []; -#[no_mangle] -pub unsafe fn instr16_EA(new_ip: i32, cs: i32) { - // jmpf - far_jump(new_ip, cs, false, false); - dbg_assert!(*is_32 || get_real_eip() < 0x10000); -} -#[no_mangle] -pub unsafe fn instr32_EA(new_ip: i32, cs: i32) { - // jmpf - far_jump(new_ip, cs, false, true); - dbg_assert!(*is_32 || get_real_eip() < 0x10000); -} + if(encoding.task_switch_test || encoding.sse) + { + instruction_prefix.push( + { + type: "if-else", + if_blocks: [ + { + condition: encoding.sse ? "!task_switch_test_mmx()" : "!task_switch_test()", + body: ["return;"], + } + ], + }); + } + + const imm_read = gen_read_imm_call(encoding, size); + const instruction_name = make_instruction_name(encoding, size); + + if(encoding.e) + { + // instruction with modrm byte -pub unsafe fn instr16_EB(imm8: i32) { - // jmp near - jmp_rel16(imm8); - dbg_assert!(*is_32 || get_real_eip() < 0x10000); -} -pub unsafe fn instr32_EB(imm8: i32) { - // jmp near - *instruction_pointer = *instruction_pointer + imm8; - dbg_assert!(*is_32 || get_real_eip() < 0x10000); -} + const imm_read = gen_read_imm_call(encoding, size); -#[no_mangle] -pub unsafe fn instr_EC() { - let port = read_reg16(DX); - if test_privileges_for_io(port, 1) { - write_reg8(AL, io_port_read8(port)); - } -} -#[no_mangle] -pub unsafe fn instr16_ED() { - let port = read_reg16(DX); - if test_privileges_for_io(port, 2) { - write_reg16(AX, io_port_read16(port)); - } -} -#[no_mangle] -pub unsafe fn instr32_ED() { - let port = read_reg16(DX); - if test_privileges_for_io(port, 4) { - write_reg32(EAX, io_port_read32(port)); - } -} -#[no_mangle] -pub unsafe fn instr_EE() { - let port = read_reg16(DX); - if test_privileges_for_io(port, 1) { - io_port_write8(port, read_reg8(AL)); - } -} -#[no_mangle] -pub unsafe fn instr16_EF() { - let port = read_reg16(DX); - if test_privileges_for_io(port, 2) { - io_port_write16(port, read_reg16(AX)); - } -} -#[no_mangle] -pub unsafe fn instr32_EF() { - let port = read_reg16(DX); - if test_privileges_for_io(port, 4) { - io_port_write32(port, read_reg32(EAX)); - } -} + if(encoding.ignore_mod) + { + assert(!imm_read, "Unexpected instruction (ignore mod with immediate value)"); + + // Has modrm byte, but the 2 mod bits are ignored and both + // operands are always registers (0f20-0f24) -pub unsafe fn instr_F0() { - // lock - if false { - dbg_log!("lock"); + return [].concat( + instruction_prefix, + gen_call(instruction_name, ["modrm_byte & 7", "modrm_byte >> 3 & 7"]), + instruction_postfix + ); + } + else + { + let mem_args; + + if(encoding.custom_modrm_resolve) + { + // requires special handling around modrm_resolve + mem_args = ["modrm_byte"]; + } + else + { + mem_args = ["match modrm_resolve(modrm_byte) { Ok(a) => a, Err(()) => return }"]; + } + + const reg_args = ["modrm_byte & 7"]; + + if(encoding.fixed_g === undefined) + { + mem_args.push("modrm_byte >> 3 & 7"); + reg_args.push("modrm_byte >> 3 & 7"); + } + + if(imm_read) + { + mem_args.push(imm_read); + reg_args.push(imm_read); + } + + return [].concat( + instruction_prefix, + { + type: "if-else", + if_blocks: [ + { + condition: "modrm_byte < 0xC0", + body: [].concat( + gen_call(`${instruction_name}_mem`, mem_args) + ), + } + ], + else_block: { + body: [gen_call(`${instruction_name}_reg`, reg_args)], + }, + }, + instruction_postfix + ); + } } - // TODO - // This triggers UD when used with - // some instructions that don't write to memory - run_prefix_instruction(); -} + else + { + const args = []; -#[no_mangle] -pub unsafe fn instr_F1() { - // INT1 - // https://code.google.com/p/corkami/wiki/x86oddities#IceBP - dbg_assert!(false); -} + if(imm_read) + { + args.push(imm_read); + } -pub unsafe fn instr_F2() { - // repnz - dbg_assert!(*prefixes & prefix::PREFIX_MASK_REP == 0); - *prefixes |= prefix::PREFIX_REPNZ; - run_prefix_instruction(); - *prefixes = 0; -} -pub unsafe fn instr_F3() { - // repz - dbg_assert!(*prefixes & prefix::PREFIX_MASK_REP == 0); - *prefixes |= prefix::PREFIX_REPZ; - run_prefix_instruction(); - *prefixes = 0; -} + if(encoding.extra_imm16) + { + assert(imm_read); + args.push(wrap_imm_call("read_imm16()")); + } + else if(encoding.extra_imm8) + { + assert(imm_read); + args.push(wrap_imm_call("read_imm8()")); + } -#[no_mangle] -pub unsafe fn instr_F4() { - if 0 != *cpl { - dbg_log!("#gp hlt with cpl != 0"); - trigger_gp(0); - return; + return [].concat( + instruction_prefix, + gen_call(instruction_name, args), + instruction_postfix + ); } - - hlt_op(); -} -#[no_mangle] -pub unsafe fn instr_F5() { - // cmc - *flags = (*flags | 1) ^ getcf() as i32; - *flags_changed &= !1; -} - -pub unsafe fn instr_F6_0_mem(addr: i32, imm: i32) { - test8(return_on_pagefault!(safe_read8(addr)), imm); -} -pub unsafe fn instr_F6_0_reg(r1: i32, imm: i32) { test8(read_reg8(r1), imm); } -pub unsafe fn instr_F6_1_mem(addr: i32, imm: i32) { - test8(return_on_pagefault!(safe_read8(addr)), imm); -} -pub unsafe fn instr_F6_1_reg(r1: i32, imm: i32) { test8(read_reg8(r1), imm); } - -#[no_mangle] -pub unsafe fn instr_F6_2_mem(addr: i32) { safe_read_write8(addr, &|x| !x & 0xFF) } -#[no_mangle] -pub unsafe fn instr_F6_2_reg(r1: i32) { write_reg8(r1, !read_reg8(r1)); } -#[no_mangle] -pub unsafe fn instr_F6_3_mem(addr: i32) { safe_read_write8(addr, &|x| neg8(x)) } -#[no_mangle] -pub unsafe fn instr_F6_3_reg(r1: i32) { write_reg8(r1, neg8(read_reg8(r1))); } -#[no_mangle] -pub unsafe fn instr_F6_4_mem(addr: i32) { mul8(return_on_pagefault!(safe_read8(addr))); } -#[no_mangle] -pub unsafe fn instr_F6_4_reg(r1: i32) { mul8(read_reg8(r1)); } -#[no_mangle] -pub unsafe fn instr_F6_5_mem(addr: i32) { - imul8(return_on_pagefault!(safe_read8(addr)) << 24 >> 24); -} -#[no_mangle] -pub unsafe fn instr_F6_5_reg(r1: i32) { imul8(read_reg8(r1) << 24 >> 24); } -#[no_mangle] -pub unsafe fn instr_F6_6_mem(addr: i32) { div8(return_on_pagefault!(safe_read8(addr)) as u32); } -#[no_mangle] -pub unsafe fn instr_F6_6_reg(r1: i32) { div8(read_reg8(r1) as u32); } -#[no_mangle] -pub unsafe fn instr_F6_7_mem(addr: i32) { - idiv8(return_on_pagefault!(safe_read8(addr)) << 24 >> 24); } -#[no_mangle] -pub unsafe fn instr_F6_7_reg(r1: i32) { idiv8(read_reg8(r1) << 24 >> 24); } -pub unsafe fn instr16_F7_0_mem(addr: i32, imm: i32) { - test16(return_on_pagefault!(safe_read16(addr)), imm); -} -pub unsafe fn instr16_F7_0_reg(r1: i32, imm: i32) { test16(read_reg16(r1), imm); } -pub unsafe fn instr16_F7_1_mem(addr: i32, imm: i32) { - test16(return_on_pagefault!(safe_read16(addr)), imm); -} -pub unsafe fn instr16_F7_1_reg(r1: i32, imm: i32) { test16(read_reg16(r1), imm); } -pub unsafe fn instr16_F7_2_mem(addr: i32) { safe_read_write16(addr, &|x| !x & 0xFFFF) } -pub unsafe fn instr16_F7_2_reg(r1: i32) { write_reg16(r1, !read_reg16(r1)); } -pub unsafe fn instr16_F7_3_mem(addr: i32) { safe_read_write16(addr, &|x| neg16(x)) } -pub unsafe fn instr16_F7_3_reg(r1: i32) { write_reg16(r1, neg16(read_reg16(r1))); } -pub unsafe fn instr16_F7_4_mem(addr: i32) { mul16(return_on_pagefault!(safe_read16(addr)) as u32); } -pub unsafe fn instr16_F7_4_reg(r1: i32) { mul16(read_reg16(r1) as u32); } -pub unsafe fn instr16_F7_5_mem(addr: i32) { - imul16(return_on_pagefault!(safe_read16(addr)) << 16 >> 16); -} -pub unsafe fn instr16_F7_5_reg(r1: i32) { imul16(read_reg16(r1) << 16 >> 16); } -pub unsafe fn instr16_F7_6_mem(addr: i32) { div16(return_on_pagefault!(safe_read16(addr)) as u32); } -pub unsafe fn instr16_F7_6_reg(r1: i32) { div16(read_reg16(r1) as u32); } -pub unsafe fn instr16_F7_7_mem(addr: i32) { - idiv16(return_on_pagefault!(safe_read16(addr)) << 16 >> 16); -} -pub unsafe fn instr16_F7_7_reg(r1: i32) { idiv16(read_reg16(r1) << 16 >> 16); } +function gen_table() +{ + let by_opcode = Object.create(null); + let by_opcode0f = Object.create(null); -pub unsafe fn instr32_F7_0_mem(addr: i32, imm: i32) { - test32(return_on_pagefault!(safe_read32s(addr)), imm); -} -pub unsafe fn instr32_F7_0_reg(r1: i32, imm: i32) { test32(read_reg32(r1), imm); } -pub unsafe fn instr32_F7_1_mem(addr: i32, imm: i32) { - test32(return_on_pagefault!(safe_read32s(addr)), imm); -} -pub unsafe fn instr32_F7_1_reg(r1: i32, imm: i32) { test32(read_reg32(r1), imm); } -pub unsafe fn instr32_F7_2_mem(addr: i32) { safe_read_write32(addr, &|x| !x) } -pub unsafe fn instr32_F7_2_reg(r1: i32) { write_reg32(r1, !read_reg32(r1)); } -pub unsafe fn instr32_F7_3_mem(addr: i32) { safe_read_write32(addr, &|x| neg32(x)) } -pub unsafe fn instr32_F7_3_reg(r1: i32) { write_reg32(r1, neg32(read_reg32(r1))); } -pub unsafe fn instr32_F7_4_mem(addr: i32) { mul32(return_on_pagefault!(safe_read32s(addr))); } -pub unsafe fn instr32_F7_4_reg(r1: i32) { mul32(read_reg32(r1)); } -pub unsafe fn instr32_F7_5_mem(addr: i32) { imul32(return_on_pagefault!(safe_read32s(addr))); } -pub unsafe fn instr32_F7_5_reg(r1: i32) { imul32(read_reg32(r1)); } -pub unsafe fn instr32_F7_6_mem(addr: i32) { - div32(return_on_pagefault!(safe_read32s(addr)) as u32); -} -pub unsafe fn instr32_F7_6_reg(r1: i32) { div32(read_reg32(r1) as u32); } -pub unsafe fn instr32_F7_7_mem(addr: i32) { idiv32(return_on_pagefault!(safe_read32s(addr))); } -pub unsafe fn instr32_F7_7_reg(r1: i32) { idiv32(read_reg32(r1)); } - -pub unsafe fn instr_F8() { - // clc - *flags &= !FLAG_CARRY; - *flags_changed &= !1; -} -pub unsafe fn instr_F9() { - // stc - *flags |= FLAG_CARRY; - *flags_changed &= !1; -} -#[no_mangle] -pub unsafe fn instr_FA_without_fault() -> bool { - // cli - if !*protected_mode - || if 0 != *flags & FLAG_VM { getiopl() == 3 } else { getiopl() >= *cpl as i32 } + for(let o of x86_table) { - *flags &= !FLAG_INTERRUPT; - return true; - } - else if false - && getiopl() < 3 - && if 0 != *flags & FLAG_VM { - 0 != *cr.offset(4) & CR4_VME + let opcode = o.opcode; + + if((opcode & 0xFF00) === 0x0F00) + { + opcode &= 0xFF; + by_opcode0f[opcode] = by_opcode0f[opcode] || []; + by_opcode0f[opcode].push(o); } - else { - *cpl == 3 && 0 != *cr.offset(4) & CR4_PVI + else + { + opcode &= 0xFF; + by_opcode[opcode] = by_opcode[opcode] || []; + by_opcode[opcode].push(o); } - { - *flags &= !FLAG_VIF; - return true; } - else { - dbg_log!("cli #gp"); - return false; - }; -} -pub unsafe fn instr_FA() { - if !instr_FA_without_fault() { - trigger_gp(0); - } -} -#[no_mangle] -pub unsafe fn instr_FB_without_fault() -> bool { - // sti - if !*protected_mode - || if 0 != *flags & FLAG_VM { getiopl() == 3 } else { getiopl() >= *cpl as i32 } + let cases = []; + for(let opcode = 0; opcode < 0x100; opcode++) { - *flags |= FLAG_INTERRUPT; - return true; - } - else if false - && getiopl() < 3 - && *flags & FLAG_VIP == 0 - && if 0 != *flags & FLAG_VM { - 0 != *cr.offset(4) & CR4_VME + let encoding = by_opcode[opcode]; + assert(encoding && encoding.length); + + let opcode_hex = hex(opcode, 2); + let opcode_high_hex = hex(opcode | 0x100, 2); + + if(encoding[0].os) + { + cases.push({ + conditions: [`0x${opcode_hex}`], + body: gen_instruction_body(encoding, 16), + }); + cases.push({ + conditions: [`0x${opcode_high_hex}`], + body: gen_instruction_body(encoding, 32), + }); } - else { - *cpl == 3 && 0 != *cr.offset(4) & CR4_PVI + else + { + cases.push({ + conditions: [`0x${opcode_hex}`, `0x${opcode_high_hex}`], + body: gen_instruction_body(encoding, undefined), + }); } - { - *flags |= FLAG_VIF; - return true; } - else { - dbg_log!("sti #gp"); - return false; + const table = { + type: "switch", + condition: "opcode", + cases, + default_case: { + body: ["assert!(false);"] + }, }; -} -pub unsafe fn instr_FB() { - if !instr_FB_without_fault() { - trigger_gp(0); - } - else { - *prefixes = 0; - *previous_ip = *instruction_pointer; - *instruction_counter += 1; - run_instruction(return_on_pagefault!(read_imm8()) | (is_osize_32() as i32) << 8); - - handle_irqs(); - } -} + if(to_generate.interpreter) + { + const code = [ + "#![cfg_attr(rustfmt, rustfmt_skip)]", -pub unsafe fn instr_FC() { - // cld - *flags &= !FLAG_DIRECTION; -} -pub unsafe fn instr_FD() { - // std - *flags |= FLAG_DIRECTION; -} + "use cpu::cpu::{after_block_boundary, modrm_resolve};", + "use cpu::cpu::{read_imm8, read_imm8s, read_imm16, read_imm32s, read_moffs};", + "use cpu::cpu::{task_switch_test, trigger_ud, DEBUG};", + "use cpu::instructions;", + "use cpu::global_pointers::{instruction_pointer, prefixes};", -pub unsafe fn instr_FE_0_mem(addr: i32) { safe_read_write8(addr, &|x| inc8(x)) } -pub unsafe fn instr_FE_0_reg(r1: i32) { write_reg8(r1, inc8(read_reg8(r1))); } -pub unsafe fn instr_FE_1_mem(addr: i32) { safe_read_write8(addr, &|x| dec8(x)) } -pub unsafe fn instr_FE_1_reg(r1: i32) { write_reg8(r1, dec8(read_reg8(r1))); } -pub unsafe fn instr16_FF_0_mem(addr: i32) { safe_read_write16(addr, &|x| inc16(x)) } -pub unsafe fn instr16_FF_0_reg(r1: i32) { write_reg16(r1, inc16(read_reg16(r1))); } -pub unsafe fn instr16_FF_1_mem(addr: i32) { safe_read_write16(addr, &|x| dec16(x)) } -pub unsafe fn instr16_FF_1_reg(r1: i32) { write_reg16(r1, dec16(read_reg16(r1))); } -pub unsafe fn instr16_FF_2_helper(data: i32) { - // call near - let cs = get_seg_cs(); - return_on_pagefault!(push16(get_real_eip())); - *instruction_pointer = cs + data; - dbg_assert!(*is_32 || get_real_eip() < 0x10000); -} -pub unsafe fn instr16_FF_2_mem(addr: i32) { - instr16_FF_2_helper(return_on_pagefault!(safe_read16(addr))); -} -pub unsafe fn instr16_FF_2_reg(r1: i32) { instr16_FF_2_helper(read_reg16(r1)); } + "pub unsafe fn run(opcode: u32) {", + table, + "}", + ]; -#[no_mangle] -pub unsafe fn instr16_FF_3_reg(_r: i32) { - dbg_log!("callf #ud"); - trigger_ud(); -} -#[no_mangle] -pub unsafe fn instr16_FF_3_mem(addr: i32) { - // callf - let new_ip = return_on_pagefault!(safe_read16(addr)); - let new_cs = return_on_pagefault!(safe_read16(addr + 2)); - far_jump(new_ip, new_cs, true, false); - dbg_assert!(*is_32 || get_real_eip() < 0x10000); -} -pub unsafe fn instr16_FF_4_helper(data: i32) { - // jmp near - *instruction_pointer = get_seg_cs() + data; - dbg_assert!(*is_32 || get_real_eip() < 0x10000); -} -pub unsafe fn instr16_FF_4_mem(addr: i32) { - instr16_FF_4_helper(return_on_pagefault!(safe_read16(addr))); -} -pub unsafe fn instr16_FF_4_reg(r1: i32) { instr16_FF_4_helper(read_reg16(r1)); } - -#[no_mangle] -pub unsafe fn instr16_FF_5_reg(_r: i32) { - dbg_log!("jmpf #ud"); - trigger_ud(); -} -#[no_mangle] -pub unsafe fn instr16_FF_5_mem(addr: i32) { - // jmpf - let new_ip = return_on_pagefault!(safe_read16(addr)); - let new_cs = return_on_pagefault!(safe_read16(addr + 2)); - far_jump(new_ip, new_cs, false, false); - dbg_assert!(*is_32 || get_real_eip() < 0x10000); -} -pub unsafe fn instr16_FF_6_mem(addr: i32) { - return_on_pagefault!(push16(return_on_pagefault!(safe_read16(addr)))); -} -pub unsafe fn instr16_FF_6_reg(r1: i32) { - return_on_pagefault!(push16(read_reg16(r1))); -} + finalize_table_rust( + OUT_DIR, + "interpreter.rs", + rust_ast.print_syntax_tree([].concat(code)).join("\n") + "\n" + ); + } -pub unsafe fn instr32_FF_0_mem(addr: i32) { safe_read_write32(addr, &|x| inc32(x)) } -pub unsafe fn instr32_FF_0_reg(r1: i32) { write_reg32(r1, inc32(read_reg32(r1))); } -pub unsafe fn instr32_FF_1_mem(addr: i32) { safe_read_write32(addr, &|x| dec32(x)) } -pub unsafe fn instr32_FF_1_reg(r1: i32) { write_reg32(r1, dec32(read_reg32(r1))); } - -pub unsafe fn instr32_FF_2_helper(data: i32) { - // call near - let cs = get_seg_cs(); - return_on_pagefault!(push32(get_real_eip())); - dbg_assert!(*is_32 || data < 0x10000); - *instruction_pointer = cs + data; -} -pub unsafe fn instr32_FF_2_mem(addr: i32) { - instr32_FF_2_helper(return_on_pagefault!(safe_read32s(addr))); -} -pub unsafe fn instr32_FF_2_reg(r1: i32) { instr32_FF_2_helper(read_reg32(r1)); } -#[no_mangle] -pub unsafe fn instr32_FF_3_reg(_r: i32) { - dbg_log!("callf #ud"); - trigger_ud(); -} -#[no_mangle] -pub unsafe fn instr32_FF_3_mem(addr: i32) { - // callf - let new_ip = return_on_pagefault!(safe_read32s(addr)); - let new_cs = return_on_pagefault!(safe_read16(addr + 4)); - if !*protected_mode || vm86_mode() { - if 0 != new_ip as u32 & 0xFFFF0000 { - dbg_assert!(false); + const cases0f = []; + for(let opcode = 0; opcode < 0x100; opcode++) + { + let encoding = by_opcode0f[opcode]; + + assert(encoding && encoding.length); + + let opcode_hex = hex(opcode, 2); + let opcode_high_hex = hex(opcode | 0x100, 2); + + if(encoding[0].os) + { + cases0f.push({ + conditions: [`0x${opcode_hex}`], + body: gen_instruction_body(encoding, 16), + }); + cases0f.push({ + conditions: [`0x${opcode_high_hex}`], + body: gen_instruction_body(encoding, 32), + }); + } + else + { + let block = { + conditions: [`0x${opcode_hex}`, `0x${opcode_high_hex}`], + body: gen_instruction_body(encoding, undefined), + }; + cases0f.push(block); } } - far_jump(new_ip, new_cs, true, true); - dbg_assert!(*is_32 || new_ip < 0x10000); -} -pub unsafe fn instr32_FF_4_helper(data: i32) { - // jmp near - dbg_assert!(*is_32 || data < 0x10000); - *instruction_pointer = get_seg_cs() + data; -} -pub unsafe fn instr32_FF_4_mem(addr: i32) { - instr32_FF_4_helper(return_on_pagefault!(safe_read32s(addr))); -} -pub unsafe fn instr32_FF_4_reg(r1: i32) { instr32_FF_4_helper(read_reg32(r1)); } + const table0f = { + type: "switch", + condition: "opcode", + cases: cases0f, + default_case: { + body: ["assert!(false);"] + }, + }; -#[no_mangle] -pub unsafe fn instr32_FF_5_reg(_r: i32) { - dbg_log!("jmpf #ud"); - trigger_ud(); -} -#[no_mangle] -pub unsafe fn instr32_FF_5_mem(addr: i32) { - // jmpf - let new_ip = return_on_pagefault!(safe_read32s(addr)); - let new_cs = return_on_pagefault!(safe_read16(addr + 4)); - if !*protected_mode || vm86_mode() { - if 0 != new_ip as u32 & 0xFFFF0000 { - dbg_assert!(false); - } + if(to_generate.interpreter0f) + { + const code = [ + "#![cfg_attr(rustfmt, rustfmt_skip)]", + + "use cpu::cpu::{after_block_boundary, modrm_resolve};", + "use cpu::cpu::{read_imm8, read_imm16, read_imm32s};", + "use cpu::cpu::{task_switch_test, task_switch_test_mmx, trigger_ud};", + "use cpu::cpu::DEBUG;", + "use cpu::instructions_0f;", + "use cpu::global_pointers::{instruction_pointer, prefixes};", + + "pub unsafe fn run(opcode: u32) {", + table0f, + "}", + ]; + + finalize_table_rust( + OUT_DIR, + "interpreter0f.rs", + rust_ast.print_syntax_tree([].concat(code)).join("\n") + "\n" + ); } - far_jump(new_ip, new_cs, false, true); - dbg_assert!(*is_32 || new_ip < 0x10000); -} -pub unsafe fn instr32_FF_6_mem(addr: i32) { - return_on_pagefault!(push32(return_on_pagefault!(safe_read32s(addr)))); -} -pub unsafe fn instr32_FF_6_reg(r1: i32) { - return_on_pagefault!(push32(read_reg32(r1))); } From 373855a332d65e18aedf3c479022a49074bad6d4 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 5 Sep 2023 16:44:21 +0200 Subject: [PATCH 039/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 2863 +++++++++++++++++++++++++++++----- 1 file changed, 2448 insertions(+), 415 deletions(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index f2f94bbf7b..f7e0ba1bad 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1,492 +1,2525 @@ -#!/usr/bin/env node -"use strict"; +#![allow(non_snake_case)] -const assert = require("assert").strict; -const fs = require("fs"); -const path = require("path"); -const x86_table = require("./x86_table"); -const rust_ast = require("./rust_ast"); -const { hex, mkdirpSync, get_switch_value, get_switch_exist, finalize_table_rust } = require("./util"); +extern "C" { + fn hlt_op(); +} -const OUT_DIR = path.join(__dirname, "..", "src/rust/gen/"); +use prefix; +use cpu::arith::*; +use cpu::cpu::*; +use cpu::fpu::*; +use cpu::global_pointers::*; +use cpu::misc_instr::*; +use cpu::misc_instr::{pop16, pop32s, push16, push32}; +use cpu::string::*; +use softfloat::F80; + +pub unsafe fn instr_00_mem(addr: i32, r: i32) { safe_read_write8(addr, &|x| add8(x, read_reg8(r))) } +pub unsafe fn instr_00_reg(r1: i32, r: i32) { write_reg8(r1, add8(read_reg8(r1), read_reg8(r))); } +pub unsafe fn instr16_01_mem(addr: i32, r: i32) { + safe_read_write16(addr, &|x| add16(x, read_reg16(r))) +} +pub unsafe fn instr16_01_reg(r1: i32, r: i32) { + write_reg16(r1, add16(read_reg16(r1), read_reg16(r))); +} +pub unsafe fn instr32_01_mem(addr: i32, r: i32) { + safe_read_write32(addr, &|x| add32(x, read_reg32(r))) +} +pub unsafe fn instr32_01_reg(r1: i32, r: i32) { + write_reg32(r1, add32(read_reg32(r1), read_reg32(r))); +} +pub unsafe fn instr_02_mem(addr: i32, r: i32) { + write_reg8( + r, + add8(read_reg8(r), return_on_pagefault!(safe_read8(addr))), + ); +} +pub unsafe fn instr_02_reg(r1: i32, r: i32) { write_reg8(r, add8(read_reg8(r), read_reg8(r1))); } +pub unsafe fn instr16_03_mem(addr: i32, r: i32) { + write_reg16( + r, + add16(read_reg16(r), return_on_pagefault!(safe_read16(addr))), + ); +} +pub unsafe fn instr16_03_reg(r1: i32, r: i32) { + write_reg16(r, add16(read_reg16(r), read_reg16(r1))); +} +pub unsafe fn instr32_03_mem(addr: i32, r: i32) { + write_reg32( + r, + add32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))), + ); +} +pub unsafe fn instr32_03_reg(r1: i32, r: i32) { + write_reg32(r, add32(read_reg32(r), read_reg32(r1))); +} +pub unsafe fn instr_04(imm8: i32) { write_reg8(AL, add8(read_reg8(AL), imm8)); } +pub unsafe fn instr16_05(imm16: i32) { write_reg16(AX, add16(read_reg16(AX), imm16)); } +pub unsafe fn instr32_05(imm32: i32) { write_reg32(EAX, add32(read_reg32(EAX), imm32)); } +pub unsafe fn instr16_06() { + return_on_pagefault!(push16(*sreg.offset(ES as isize) as i32)); +} +pub unsafe fn instr32_06() { return_on_pagefault!(push32_sreg(ES)) } -mkdirpSync(OUT_DIR); +#[no_mangle] +pub unsafe fn instr16_07() { + if !switch_seg(ES, return_on_pagefault!(safe_read16(get_stack_pointer(0)))) { + return; + } + adjust_stack_reg(2); +} +#[no_mangle] +pub unsafe fn instr32_07() { + if !switch_seg( + ES, + return_on_pagefault!(safe_read32s(get_stack_pointer(0))) & 0xFFFF, + ) { + return; + } + adjust_stack_reg(4); +} -const table_arg = get_switch_value("--table"); -const gen_all = get_switch_exist("--all"); -const to_generate = { - interpreter: gen_all || table_arg === "interpreter", - interpreter0f: gen_all || table_arg === "interpreter0f", -}; +pub unsafe fn instr_08_mem(addr: i32, r: i32) { safe_read_write8(addr, &|x| or8(x, read_reg8(r))) } +pub unsafe fn instr_08_reg(r1: i32, r: i32) { write_reg8(r1, or8(read_reg8(r1), read_reg8(r))); } +pub unsafe fn instr16_09_mem(addr: i32, r: i32) { + safe_read_write16(addr, &|x| or16(x, read_reg16(r))) +} +pub unsafe fn instr16_09_reg(r1: i32, r: i32) { + write_reg16(r1, or16(read_reg16(r1), read_reg16(r))); +} +pub unsafe fn instr32_09_mem(addr: i32, r: i32) { + safe_read_write32(addr, &|x| or32(x, read_reg32(r))) +} +pub unsafe fn instr32_09_reg(r1: i32, r: i32) { + write_reg32(r1, or32(read_reg32(r1), read_reg32(r))); +} +pub unsafe fn instr_0A_mem(addr: i32, r: i32) { + write_reg8(r, or8(read_reg8(r), return_on_pagefault!(safe_read8(addr)))); +} +pub unsafe fn instr_0A_reg(r1: i32, r: i32) { write_reg8(r, or8(read_reg8(r), read_reg8(r1))); } +pub unsafe fn instr16_0B_mem(addr: i32, r: i32) { + write_reg16( + r, + or16(read_reg16(r), return_on_pagefault!(safe_read16(addr))), + ); +} +pub unsafe fn instr16_0B_reg(r1: i32, r: i32) { + write_reg16(r, or16(read_reg16(r), read_reg16(r1))); +} +pub unsafe fn instr32_0B_mem(addr: i32, r: i32) { + write_reg32( + r, + or32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))), + ); +} +pub unsafe fn instr32_0B_reg(r1: i32, r: i32) { + write_reg32(r, or32(read_reg32(r), read_reg32(r1))); +} +pub unsafe fn instr_0C(imm8: i32) { write_reg8(AL, or8(read_reg8(AL), imm8)); } +pub unsafe fn instr16_0D(imm16: i32) { write_reg16(AX, or16(read_reg16(AX), imm16)); } +pub unsafe fn instr32_0D(imm32: i32) { write_reg32(EAX, or32(read_reg32(EAX), imm32)); } -assert( - Object.keys(to_generate).some(k => to_generate[k]), - "Pass --table [interpreter|interpreter0f] or --all to pick which tables to generate" -); +pub unsafe fn instr16_0E() { + return_on_pagefault!(push16(*sreg.offset(CS as isize) as i32)); +} +pub unsafe fn instr32_0E() { return_on_pagefault!(push32_sreg(CS)) } -gen_table(); +pub unsafe fn instr16_0F() { run_instruction0f_16(return_on_pagefault!(read_imm8())); } +pub unsafe fn instr32_0F() { run_instruction0f_32(return_on_pagefault!(read_imm8())); } -function wrap_imm_call(imm) -{ - return `match ${imm} { Ok(o) => o, Err(()) => return }`; +pub unsafe fn instr_10_mem(addr: i32, r: i32) { safe_read_write8(addr, &|x| adc8(x, read_reg8(r))) } +pub unsafe fn instr_10_reg(r1: i32, r: i32) { write_reg8(r1, adc8(read_reg8(r1), read_reg8(r))); } +pub unsafe fn instr16_11_mem(addr: i32, r: i32) { + safe_read_write16(addr, &|x| adc16(x, read_reg16(r))) +} +pub unsafe fn instr16_11_reg(r1: i32, r: i32) { + write_reg16(r1, adc16(read_reg16(r1), read_reg16(r))); +} +pub unsafe fn instr32_11_mem(addr: i32, r: i32) { + safe_read_write32(addr, &|x| adc32(x, read_reg32(r))) +} +pub unsafe fn instr32_11_reg(r1: i32, r: i32) { + write_reg32(r1, adc32(read_reg32(r1), read_reg32(r))); +} +pub unsafe fn instr_12_mem(addr: i32, r: i32) { + write_reg8( + r, + adc8(read_reg8(r), return_on_pagefault!(safe_read8(addr))), + ); +} +pub unsafe fn instr_12_reg(r1: i32, r: i32) { write_reg8(r, adc8(read_reg8(r), read_reg8(r1))); } +pub unsafe fn instr16_13_mem(addr: i32, r: i32) { + write_reg16( + r, + adc16(read_reg16(r), return_on_pagefault!(safe_read16(addr))), + ); +} +pub unsafe fn instr16_13_reg(r1: i32, r: i32) { + write_reg16(r, adc16(read_reg16(r), read_reg16(r1))); } +pub unsafe fn instr32_13_mem(addr: i32, r: i32) { + write_reg32( + r, + adc32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))), + ); +} +pub unsafe fn instr32_13_reg(r1: i32, r: i32) { + write_reg32(r, adc32(read_reg32(r), read_reg32(r1))); +} +pub unsafe fn instr_14(imm8: i32) { write_reg8(AL, adc8(read_reg8(AL), imm8)); } +pub unsafe fn instr16_15(imm16: i32) { write_reg16(AX, adc16(read_reg16(AX), imm16)); } +pub unsafe fn instr32_15(imm32: i32) { write_reg32(EAX, adc32(read_reg32(EAX), imm32)); } -function gen_read_imm_call(op, size_variant) -{ - let size = (op.os || op.opcode % 2 === 1) ? size_variant : 8; +pub unsafe fn instr16_16() { + return_on_pagefault!(push16(*sreg.offset(SS as isize) as i32)); +} +pub unsafe fn instr32_16() { return_on_pagefault!(push32_sreg(SS)) } - if(op.imm8 || op.imm8s || op.imm16 || op.imm1632 || op.imm32 || op.immaddr) - { - if(op.imm8) - { - return wrap_imm_call("read_imm8()"); - } - else if(op.imm8s) - { - return wrap_imm_call("read_imm8s()"); - } - else - { - if(op.immaddr) - { - // immaddr: depends on address size - return wrap_imm_call("read_moffs()"); - } - else - { - assert(op.imm1632 || op.imm16 || op.imm32); - - if(op.imm1632 && size === 16 || op.imm16) - { - return wrap_imm_call("read_imm16()"); - } - else - { - assert(op.imm1632 && size === 32 || op.imm32); - return wrap_imm_call("read_imm32s()"); - } - } - } +#[no_mangle] +pub unsafe fn instr16_17() { + if !switch_seg(SS, return_on_pagefault!(safe_read16(get_stack_pointer(0)))) { + return; } - else - { - return undefined; + adjust_stack_reg(2); +} +#[no_mangle] +pub unsafe fn instr32_17() { + if !switch_seg( + SS, + return_on_pagefault!(safe_read32s(get_stack_pointer(0))) & 0xFFFF, + ) { + return; + } + adjust_stack_reg(4); +} + +pub unsafe fn instr_18_mem(addr: i32, r: i32) { safe_read_write8(addr, &|x| sbb8(x, read_reg8(r))) } +pub unsafe fn instr_18_reg(r1: i32, r: i32) { write_reg8(r1, sbb8(read_reg8(r1), read_reg8(r))); } +pub unsafe fn instr16_19_mem(addr: i32, r: i32) { + safe_read_write16(addr, &|x| sbb16(x, read_reg16(r))) +} +pub unsafe fn instr16_19_reg(r1: i32, r: i32) { + write_reg16(r1, sbb16(read_reg16(r1), read_reg16(r))); +} +pub unsafe fn instr32_19_mem(addr: i32, r: i32) { + safe_read_write32(addr, &|x| sbb32(x, read_reg32(r))) +} +pub unsafe fn instr32_19_reg(r1: i32, r: i32) { + write_reg32(r1, sbb32(read_reg32(r1), read_reg32(r))); +} +pub unsafe fn instr_1A_mem(addr: i32, r: i32) { + write_reg8( + r, + sbb8(read_reg8(r), return_on_pagefault!(safe_read8(addr))), + ); +} +pub unsafe fn instr_1A_reg(r1: i32, r: i32) { write_reg8(r, sbb8(read_reg8(r), read_reg8(r1))); } +pub unsafe fn instr16_1B_mem(addr: i32, r: i32) { + write_reg16( + r, + sbb16(read_reg16(r), return_on_pagefault!(safe_read16(addr))), + ); +} +pub unsafe fn instr16_1B_reg(r1: i32, r: i32) { + write_reg16(r, sbb16(read_reg16(r), read_reg16(r1))); +} +pub unsafe fn instr32_1B_mem(addr: i32, r: i32) { + write_reg32( + r, + sbb32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))), + ); +} +pub unsafe fn instr32_1B_reg(r1: i32, r: i32) { + write_reg32(r, sbb32(read_reg32(r), read_reg32(r1))); +} +pub unsafe fn instr_1C(imm8: i32) { write_reg8(AL, sbb8(read_reg8(AL), imm8)); } +pub unsafe fn instr16_1D(imm16: i32) { write_reg16(AX, sbb16(read_reg16(AX), imm16)); } +pub unsafe fn instr32_1D(imm32: i32) { write_reg32(EAX, sbb32(read_reg32(EAX), imm32)); } + +pub unsafe fn instr16_1E() { + return_on_pagefault!(push16(*sreg.offset(DS as isize) as i32)); +} +pub unsafe fn instr32_1E() { return_on_pagefault!(push32_sreg(DS)) } + +#[no_mangle] +pub unsafe fn instr16_1F() { + if !switch_seg(DS, return_on_pagefault!(safe_read16(get_stack_pointer(0)))) { + return; + } + adjust_stack_reg(2); +} +#[no_mangle] +pub unsafe fn instr32_1F() { + if !switch_seg( + DS, + return_on_pagefault!(safe_read32s(get_stack_pointer(0))) & 0xFFFF, + ) { + return; } + adjust_stack_reg(4); +} + +pub unsafe fn instr_20_mem(addr: i32, r: i32) { safe_read_write8(addr, &|x| and8(x, read_reg8(r))) } +pub unsafe fn instr_20_reg(r1: i32, r: i32) { write_reg8(r1, and8(read_reg8(r1), read_reg8(r))); } +pub unsafe fn instr16_21_mem(addr: i32, r: i32) { + safe_read_write16(addr, &|x| and16(x, read_reg16(r))) +} +pub unsafe fn instr16_21_reg(r1: i32, r: i32) { + write_reg16(r1, and16(read_reg16(r1), read_reg16(r))); +} +pub unsafe fn instr32_21_mem(addr: i32, r: i32) { + safe_read_write32(addr, &|x| and32(x, read_reg32(r))) } +pub unsafe fn instr32_21_reg(r1: i32, r: i32) { + write_reg32(r1, and32(read_reg32(r1), read_reg32(r))); +} +pub unsafe fn instr_22_mem(addr: i32, r: i32) { + write_reg8( + r, + and8(read_reg8(r), return_on_pagefault!(safe_read8(addr))), + ); +} +pub unsafe fn instr_22_reg(r1: i32, r: i32) { write_reg8(r, and8(read_reg8(r), read_reg8(r1))); } +pub unsafe fn instr16_23_mem(addr: i32, r: i32) { + write_reg16( + r, + and16(read_reg16(r), return_on_pagefault!(safe_read16(addr))), + ); +} +pub unsafe fn instr16_23_reg(r1: i32, r: i32) { + write_reg16(r, and16(read_reg16(r), read_reg16(r1))); +} +pub unsafe fn instr32_23_mem(addr: i32, r: i32) { + write_reg32( + r, + and32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))), + ); +} +pub unsafe fn instr32_23_reg(r1: i32, r: i32) { + write_reg32(r, and32(read_reg32(r), read_reg32(r1))); +} +pub unsafe fn instr_24(imm8: i32) { write_reg8(AL, and8(read_reg8(AL), imm8)); } +pub unsafe fn instr16_25(imm16: i32) { write_reg16(AX, and16(read_reg16(AX), imm16)); } +pub unsafe fn instr32_25(imm32: i32) { write_reg32(EAX, and32(read_reg32(EAX), imm32)); } + +pub unsafe fn instr_26() { segment_prefix_op(ES); } + +#[no_mangle] +pub unsafe fn instr_27() { bcd_daa(); } -function gen_call(name, args) -{ - args = args || []; - return `${name}(${args.join(", ")});`; +pub unsafe fn instr_28_mem(addr: i32, r: i32) { safe_read_write8(addr, &|x| sub8(x, read_reg8(r))) } +pub unsafe fn instr_28_reg(r1: i32, r: i32) { write_reg8(r1, sub8(read_reg8(r1), read_reg8(r))); } +pub unsafe fn instr16_29_mem(addr: i32, r: i32) { + safe_read_write16(addr, &|x| sub16(x, read_reg16(r))) +} +pub unsafe fn instr16_29_reg(r1: i32, r: i32) { + write_reg16(r1, sub16(read_reg16(r1), read_reg16(r))); +} +pub unsafe fn instr32_29_mem(addr: i32, r: i32) { + safe_read_write32(addr, &|x| sub32(x, read_reg32(r))) +} +pub unsafe fn instr32_29_reg(r1: i32, r: i32) { + write_reg32(r1, sub32(read_reg32(r1), read_reg32(r))); +} +pub unsafe fn instr_2A_mem(addr: i32, r: i32) { + write_reg8( + r, + sub8(read_reg8(r), return_on_pagefault!(safe_read8(addr))), + ); +} +pub unsafe fn instr_2A_reg(r1: i32, r: i32) { write_reg8(r, sub8(read_reg8(r), read_reg8(r1))); } +pub unsafe fn instr16_2B_mem(addr: i32, r: i32) { + write_reg16( + r, + sub16(read_reg16(r), return_on_pagefault!(safe_read16(addr))), + ); +} +pub unsafe fn instr16_2B_reg(r1: i32, r: i32) { + write_reg16(r, sub16(read_reg16(r), read_reg16(r1))); +} +pub unsafe fn instr32_2B_mem(addr: i32, r: i32) { + write_reg32( + r, + sub32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))), + ); +} +pub unsafe fn instr32_2B_reg(r1: i32, r: i32) { + write_reg32(r, sub32(read_reg32(r), read_reg32(r1))); } +pub unsafe fn instr_2C(imm8: i32) { write_reg8(AL, sub8(read_reg8(AL), imm8)); } +pub unsafe fn instr16_2D(imm16: i32) { write_reg16(AX, sub16(read_reg16(AX), imm16)); } +pub unsafe fn instr32_2D(imm32: i32) { write_reg32(EAX, sub32(read_reg32(EAX), imm32)); } -/* - * Current naming scheme: - * instr(16|32|)_(66|F2|F3)?0F?[0-9a-f]{2}(_[0-7])?(_mem|_reg|) - */ -function make_instruction_name(encoding, size) -{ - const suffix = encoding.os ? String(size) : ""; - const opcode_hex = hex(encoding.opcode & 0xFF, 2); - const first_prefix = (encoding.opcode & 0xFF00) === 0 ? "" : hex(encoding.opcode >> 8 & 0xFF, 2); - const second_prefix = (encoding.opcode & 0xFF0000) === 0 ? "" : hex(encoding.opcode >> 16 & 0xFF, 2); - const fixed_g_suffix = encoding.fixed_g === undefined ? "" : `_${encoding.fixed_g}`; - const module = first_prefix === "0F" || second_prefix === "0F" ? "instructions_0f" : "instructions"; +pub unsafe fn instr_2E() { segment_prefix_op(CS); } - assert(first_prefix === "" || first_prefix === "0F" || first_prefix === "F2" || first_prefix === "F3"); - assert(second_prefix === "" || second_prefix === "66" || second_prefix === "F2" || second_prefix === "F3"); +#[no_mangle] +pub unsafe fn instr_2F() { bcd_das(); } - return `${module}::instr${suffix}_${second_prefix}${first_prefix}${opcode_hex}${fixed_g_suffix}`; +pub unsafe fn instr_30_mem(addr: i32, r: i32) { safe_read_write8(addr, &|x| xor8(x, read_reg8(r))) } +pub unsafe fn instr_30_reg(r1: i32, r: i32) { write_reg8(r1, xor8(read_reg8(r1), read_reg8(r))); } +pub unsafe fn instr16_31_mem(addr: i32, r: i32) { + safe_read_write16(addr, &|x| xor16(x, read_reg16(r))) } +pub unsafe fn instr16_31_reg(r1: i32, r: i32) { + write_reg16(r1, xor16(read_reg16(r1), read_reg16(r))); +} +pub unsafe fn instr32_31_mem(addr: i32, r: i32) { + safe_read_write32(addr, &|x| xor32(x, read_reg32(r))) +} +pub unsafe fn instr32_31_reg(r1: i32, r: i32) { + write_reg32(r1, xor32(read_reg32(r1), read_reg32(r))); +} +pub unsafe fn instr_32_mem(addr: i32, r: i32) { + write_reg8( + r, + xor8(read_reg8(r), return_on_pagefault!(safe_read8(addr))), + ); +} +pub unsafe fn instr_32_reg(r1: i32, r: i32) { write_reg8(r, xor8(read_reg8(r), read_reg8(r1))); } +pub unsafe fn instr16_33_mem(addr: i32, r: i32) { + write_reg16( + r, + xor16(read_reg16(r), return_on_pagefault!(safe_read16(addr))), + ); +} +pub unsafe fn instr16_33_reg(r1: i32, r: i32) { + write_reg16(r, xor16(read_reg16(r), read_reg16(r1))); +} +pub unsafe fn instr32_33_mem(addr: i32, r: i32) { + write_reg32( + r, + xor32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))), + ); +} +pub unsafe fn instr32_33_reg(r1: i32, r: i32) { + write_reg32(r, xor32(read_reg32(r), read_reg32(r1))); +} +pub unsafe fn instr_34(imm8: i32) { write_reg8(AL, xor8(read_reg8(AL), imm8)); } +pub unsafe fn instr16_35(imm16: i32) { write_reg16(AX, xor16(read_reg16(AX), imm16)); } +pub unsafe fn instr32_35(imm32: i32) { write_reg32(EAX, xor32(read_reg32(EAX), imm32)); } -function gen_instruction_body(encodings, size) -{ - const encoding = encodings[0]; +pub unsafe fn instr_36() { segment_prefix_op(SS); } - let has_66 = []; - let has_F2 = []; - let has_F3 = []; - let no_prefix = []; +#[no_mangle] +pub unsafe fn instr_37() { bcd_aaa(); } - for(let e of encodings) - { - if((e.opcode >>> 16) === 0x66) has_66.push(e); - else if((e.opcode >>> 8 & 0xFF) === 0xF2 || (e.opcode >>> 16) === 0xF2) has_F2.push(e); - else if((e.opcode >>> 8 & 0xFF) === 0xF3 || (e.opcode >>> 16) === 0xF3) has_F3.push(e); - else no_prefix.push(e); - } +pub unsafe fn instr_38_mem(addr: i32, r: i32) { + cmp8(return_on_pagefault!(safe_read8(addr)), read_reg8(r)); +} +pub unsafe fn instr_38_reg(r1: i32, r: i32) { cmp8(read_reg8(r1), read_reg8(r)); } +pub unsafe fn instr16_39_mem(addr: i32, r: i32) { + cmp16(return_on_pagefault!(safe_read16(addr)), read_reg16(r)); +} +pub unsafe fn instr16_39_reg(r1: i32, r: i32) { cmp16(read_reg16(r1), read_reg16(r)); } +pub unsafe fn instr32_39_mem(addr: i32, r: i32) { + cmp32(return_on_pagefault!(safe_read32s(addr)), read_reg32(r)); +} +pub unsafe fn instr32_39_reg(r1: i32, r: i32) { cmp32(read_reg32(r1), read_reg32(r)); } +pub unsafe fn instr_3A_mem(addr: i32, r: i32) { + cmp8(read_reg8(r), return_on_pagefault!(safe_read8(addr))); +} +pub unsafe fn instr_3A_reg(r1: i32, r: i32) { cmp8(read_reg8(r), read_reg8(r1)); } +pub unsafe fn instr16_3B_mem(addr: i32, r: i32) { + cmp16(read_reg16(r), return_on_pagefault!(safe_read16(addr))); +} +pub unsafe fn instr16_3B_reg(r1: i32, r: i32) { cmp16(read_reg16(r), read_reg16(r1)); } +pub unsafe fn instr32_3B_mem(addr: i32, r: i32) { + cmp32(read_reg32(r), return_on_pagefault!(safe_read32s(addr))); +} +pub unsafe fn instr32_3B_reg(r1: i32, r: i32) { cmp32(read_reg32(r), read_reg32(r1)); } +pub unsafe fn instr_3C(imm8: i32) { cmp8(read_reg8(AL), imm8); } +pub unsafe fn instr16_3D(imm16: i32) { cmp16(read_reg16(AX), imm16); } +pub unsafe fn instr32_3D(imm32: i32) { cmp32(read_reg32(EAX), imm32); } + +pub unsafe fn instr_3E() { segment_prefix_op(DS); } + +#[no_mangle] +pub unsafe fn instr_3F() { bcd_aas(); } + +pub unsafe fn instr16_40() { write_reg16(AX, inc16(read_reg16(AX))); } +pub unsafe fn instr32_40() { write_reg32(EAX, inc32(read_reg32(EAX))); } +pub unsafe fn instr16_41() { write_reg16(CX, inc16(read_reg16(CX))); } +pub unsafe fn instr32_41() { write_reg32(ECX, inc32(read_reg32(ECX))); } +pub unsafe fn instr16_42() { write_reg16(DX, inc16(read_reg16(DX))); } +pub unsafe fn instr32_42() { write_reg32(EDX, inc32(read_reg32(EDX))); } +pub unsafe fn instr16_43() { write_reg16(BX, inc16(read_reg16(BX))); } +pub unsafe fn instr32_43() { write_reg32(EBX, inc32(read_reg32(EBX))); } +pub unsafe fn instr16_44() { write_reg16(SP, inc16(read_reg16(SP))); } +pub unsafe fn instr32_44() { write_reg32(ESP, inc32(read_reg32(ESP))); } +pub unsafe fn instr16_45() { write_reg16(BP, inc16(read_reg16(BP))); } +pub unsafe fn instr32_45() { write_reg32(EBP, inc32(read_reg32(EBP))); } +pub unsafe fn instr16_46() { write_reg16(SI, inc16(read_reg16(SI))); } +pub unsafe fn instr32_46() { write_reg32(ESI, inc32(read_reg32(ESI))); } +pub unsafe fn instr16_47() { write_reg16(DI, inc16(read_reg16(DI))); } +pub unsafe fn instr32_47() { write_reg32(EDI, inc32(read_reg32(EDI))); } +pub unsafe fn instr16_48() { write_reg16(AX, dec16(read_reg16(AX))); } +pub unsafe fn instr32_48() { write_reg32(EAX, dec32(read_reg32(EAX))); } +pub unsafe fn instr16_49() { write_reg16(CX, dec16(read_reg16(CX))); } +pub unsafe fn instr32_49() { write_reg32(ECX, dec32(read_reg32(ECX))); } +pub unsafe fn instr16_4A() { write_reg16(DX, dec16(read_reg16(DX))); } +pub unsafe fn instr32_4A() { write_reg32(EDX, dec32(read_reg32(EDX))); } +pub unsafe fn instr16_4B() { write_reg16(BX, dec16(read_reg16(BX))); } +pub unsafe fn instr32_4B() { write_reg32(EBX, dec32(read_reg32(EBX))); } +pub unsafe fn instr16_4C() { write_reg16(SP, dec16(read_reg16(SP))); } +pub unsafe fn instr32_4C() { write_reg32(ESP, dec32(read_reg32(ESP))); } +pub unsafe fn instr16_4D() { write_reg16(BP, dec16(read_reg16(BP))); } +pub unsafe fn instr32_4D() { write_reg32(EBP, dec32(read_reg32(EBP))); } +pub unsafe fn instr16_4E() { write_reg16(SI, dec16(read_reg16(SI))); } +pub unsafe fn instr32_4E() { write_reg32(ESI, dec32(read_reg32(ESI))); } +pub unsafe fn instr16_4F() { write_reg16(DI, dec16(read_reg16(DI))); } +pub unsafe fn instr32_4F() { write_reg32(EDI, dec32(read_reg32(EDI))); } + +pub unsafe fn push16_reg(r: i32) { + return_on_pagefault!(push16(read_reg16(r))); +} +pub unsafe fn push32_reg(r: i32) { + return_on_pagefault!(push32(read_reg32(r))); +} - if(has_F2.length || has_F3.length) - { - assert((encoding.opcode & 0xFF0000) === 0 || (encoding.opcode & 0xFF00) === 0x0F00); +pub unsafe fn instr16_50() { push16_reg(AX) } +pub unsafe fn instr32_50() { push32_reg(EAX) } +pub unsafe fn instr16_51() { push16_reg(CX) } +pub unsafe fn instr32_51() { push32_reg(ECX) } +pub unsafe fn instr16_52() { push16_reg(DX) } +pub unsafe fn instr32_52() { push32_reg(EDX) } +pub unsafe fn instr16_53() { push16_reg(BX) } +pub unsafe fn instr32_53() { push32_reg(EBX) } +pub unsafe fn instr16_54() { push16_reg(SP) } +pub unsafe fn instr32_54() { push32_reg(ESP) } +pub unsafe fn instr16_55() { push16_reg(BP) } +pub unsafe fn instr32_55() { push32_reg(EBP) } +pub unsafe fn instr16_56() { push16_reg(SI) } +pub unsafe fn instr32_56() { push32_reg(ESI) } +pub unsafe fn instr16_57() { push16_reg(DI) } +pub unsafe fn instr32_57() { push32_reg(EDI) } +pub unsafe fn instr16_58() { write_reg16(AX, return_on_pagefault!(pop16())); } +pub unsafe fn instr32_58() { write_reg32(EAX, return_on_pagefault!(pop32s())); } +pub unsafe fn instr16_59() { write_reg16(CX, return_on_pagefault!(pop16())); } +pub unsafe fn instr32_59() { write_reg32(ECX, return_on_pagefault!(pop32s())); } +pub unsafe fn instr16_5A() { write_reg16(DX, return_on_pagefault!(pop16())); } +pub unsafe fn instr32_5A() { write_reg32(EDX, return_on_pagefault!(pop32s())); } +pub unsafe fn instr16_5B() { write_reg16(BX, return_on_pagefault!(pop16())); } +pub unsafe fn instr32_5B() { write_reg32(EBX, return_on_pagefault!(pop32s())); } +pub unsafe fn instr16_5C() { + write_reg16(SP, return_on_pagefault!(safe_read16(get_stack_pointer(0)))); +} +pub unsafe fn instr32_5C() { + write_reg32( + ESP, + return_on_pagefault!(safe_read32s(get_stack_pointer(0))), + ); +} +pub unsafe fn instr16_5D() { write_reg16(BP, return_on_pagefault!(pop16())); } +pub unsafe fn instr32_5D() { write_reg32(EBP, return_on_pagefault!(pop32s())); } +pub unsafe fn instr16_5E() { write_reg16(SI, return_on_pagefault!(pop16())); } +pub unsafe fn instr32_5E() { write_reg32(ESI, return_on_pagefault!(pop32s())); } +pub unsafe fn instr16_5F() { write_reg16(DI, return_on_pagefault!(pop16())); } +pub unsafe fn instr32_5F() { write_reg32(EDI, return_on_pagefault!(pop32s())); } + +#[no_mangle] +pub unsafe fn instr16_60() { pusha16(); } +#[no_mangle] +pub unsafe fn instr32_60() { pusha32(); } +#[no_mangle] +pub unsafe fn instr16_61() { popa16(); } +#[no_mangle] +pub unsafe fn instr32_61() { popa32(); } + +#[no_mangle] +pub unsafe fn instr_62_reg(_r2: i32, _r: i32) { + // bound + dbg_log!("Unimplemented BOUND instruction"); + dbg_assert!(false); +} +#[no_mangle] +pub unsafe fn instr_62_mem(_addr: i32, _r: i32) { + dbg_log!("Unimplemented BOUND instruction"); + dbg_assert!(false); +} + +pub unsafe fn arpl(seg: i32, r16: i32) -> i32 { + *flags_changed &= !FLAG_ZERO; + + if (seg & 3) < (r16 & 3) { + *flags |= FLAG_ZERO; + seg & !3 | r16 & 3 + } + else { + *flags &= !FLAG_ZERO; + seg } +} - if(has_66.length) - { - assert((encoding.opcode & 0xFF00) === 0x0F00); +#[no_mangle] +pub unsafe fn instr_63_mem(addr: i32, r: i32) { + if !*protected_mode || vm86_mode() { + dbg_log!("arpl #ud"); + trigger_ud(); + return; + } + safe_read_write16(addr, &|x| arpl(x, read_reg16(r))) +} +#[no_mangle] +pub unsafe fn instr_63_reg(r1: i32, r: i32) { + if !*protected_mode || vm86_mode() { + dbg_log!("arpl #ud"); + trigger_ud(); + return; } + write_reg16(r1, arpl(read_reg16(r1), read_reg16(r))); +} - const code = []; +pub unsafe fn instr_64() { segment_prefix_op(FS); } +pub unsafe fn instr_65() { segment_prefix_op(GS); } - if(encoding.e) - { - code.push(`let modrm_byte = ${wrap_imm_call("read_imm8()")};`); +pub unsafe fn instr_66() { + // Operand-size override prefix + *prefixes |= prefix::PREFIX_MASK_OPSIZE; + run_prefix_instruction(); + *prefixes = 0; +} +pub unsafe fn instr_67() { + // Address-size override prefix + dbg_assert!(is_asize_32() == *is_32); + *prefixes |= prefix::PREFIX_MASK_ADDRSIZE; + run_prefix_instruction(); + *prefixes = 0; +} + +pub unsafe fn instr16_68(imm16: i32) { + return_on_pagefault!(push16(imm16)); +} +pub unsafe fn instr32_68(imm32: i32) { + return_on_pagefault!(push32(imm32)); +} +pub unsafe fn instr16_69_mem(addr: i32, r: i32, imm: i32) { + write_reg16(r, imul_reg16(return_on_pagefault!(safe_read16(addr)), imm)); +} +pub unsafe fn instr16_69_reg(r1: i32, r: i32, imm: i32) { + write_reg16(r, imul_reg16(read_reg16(r1), imm)); +} +pub unsafe fn instr32_69_mem(addr: i32, r: i32, imm: i32) { + write_reg32(r, imul_reg32(return_on_pagefault!(safe_read32s(addr)), imm)); +} +pub unsafe fn instr32_69_reg(r1: i32, r: i32, imm: i32) { + write_reg32(r, imul_reg32(read_reg32(r1), imm)); +} + +pub unsafe fn instr16_6A(imm8: i32) { + return_on_pagefault!(push16(imm8)); +} +pub unsafe fn instr32_6A(imm8: i32) { + return_on_pagefault!(push32(imm8)); +} +pub unsafe fn instr16_6B_mem(addr: i32, r: i32, imm: i32) { + write_reg16(r, imul_reg16(return_on_pagefault!(safe_read16(addr)), imm)); +} +pub unsafe fn instr16_6B_reg(r1: i32, r: i32, imm: i32) { + write_reg16(r, imul_reg16(read_reg16(r1), imm)); +} +pub unsafe fn instr32_6B_mem(addr: i32, r: i32, imm: i32) { + write_reg32(r, imul_reg32(return_on_pagefault!(safe_read32s(addr)), imm)); +} +pub unsafe fn instr32_6B_reg(r1: i32, r: i32, imm: i32) { + write_reg32(r, imul_reg32(read_reg32(r1), imm)); +} + +pub unsafe fn instr_6C() { insb_no_rep(is_asize_32()); } +pub unsafe fn instr_F26C() { insb_rep(is_asize_32()); } +pub unsafe fn instr_F36C() { insb_rep(is_asize_32()); } +pub unsafe fn instr16_6D() { insw_no_rep(is_asize_32()); } +pub unsafe fn instr32_6D() { insd_no_rep(is_asize_32()); } +pub unsafe fn instr16_F26D() { insw_rep(is_asize_32()); } +pub unsafe fn instr16_F36D() { insw_rep(is_asize_32()); } +pub unsafe fn instr32_F26D() { insd_rep(is_asize_32()); } +pub unsafe fn instr32_F36D() { insd_rep(is_asize_32()); } + +pub unsafe fn instr_6E() { outsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } +pub unsafe fn instr_F26E() { outsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } +pub unsafe fn instr_F36E() { outsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } + +pub unsafe fn instr16_6F() { + outsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); +} +pub unsafe fn instr32_6F() { + outsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); +} +pub unsafe fn instr16_F26F() { outsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } +pub unsafe fn instr16_F36F() { outsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } +pub unsafe fn instr32_F26F() { outsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } +pub unsafe fn instr32_F36F() { outsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } + +pub unsafe fn instr16_70(imm8: i32) { jmpcc16(test_o(), imm8); } +pub unsafe fn instr16_71(imm8: i32) { jmpcc16(!test_o(), imm8); } +pub unsafe fn instr16_72(imm8: i32) { jmpcc16(test_b(), imm8); } +pub unsafe fn instr16_73(imm8: i32) { jmpcc16(!test_b(), imm8); } +pub unsafe fn instr16_74(imm8: i32) { jmpcc16(test_z(), imm8); } +pub unsafe fn instr16_75(imm8: i32) { jmpcc16(!test_z(), imm8); } +pub unsafe fn instr16_76(imm8: i32) { jmpcc16(test_be(), imm8); } +pub unsafe fn instr16_77(imm8: i32) { jmpcc16(!test_be(), imm8); } +pub unsafe fn instr16_78(imm8: i32) { jmpcc16(test_s(), imm8); } +pub unsafe fn instr16_79(imm8: i32) { jmpcc16(!test_s(), imm8); } +pub unsafe fn instr16_7A(imm8: i32) { jmpcc16(test_p(), imm8); } +pub unsafe fn instr16_7B(imm8: i32) { jmpcc16(!test_p(), imm8); } +pub unsafe fn instr16_7C(imm8: i32) { jmpcc16(test_l(), imm8); } +pub unsafe fn instr16_7D(imm8: i32) { jmpcc16(!test_l(), imm8); } +pub unsafe fn instr16_7E(imm8: i32) { jmpcc16(test_le(), imm8); } +pub unsafe fn instr16_7F(imm8: i32) { jmpcc16(!test_le(), imm8); } +pub unsafe fn instr32_70(imm8: i32) { jmpcc32(test_o(), imm8); } +pub unsafe fn instr32_71(imm8: i32) { jmpcc32(!test_o(), imm8); } +pub unsafe fn instr32_72(imm8: i32) { jmpcc32(test_b(), imm8); } +pub unsafe fn instr32_73(imm8: i32) { jmpcc32(!test_b(), imm8); } +pub unsafe fn instr32_74(imm8: i32) { jmpcc32(test_z(), imm8); } +pub unsafe fn instr32_75(imm8: i32) { jmpcc32(!test_z(), imm8); } +pub unsafe fn instr32_76(imm8: i32) { jmpcc32(test_be(), imm8); } +pub unsafe fn instr32_77(imm8: i32) { jmpcc32(!test_be(), imm8); } +pub unsafe fn instr32_78(imm8: i32) { jmpcc32(test_s(), imm8); } +pub unsafe fn instr32_79(imm8: i32) { jmpcc32(!test_s(), imm8); } +pub unsafe fn instr32_7A(imm8: i32) { jmpcc32(test_p(), imm8); } +pub unsafe fn instr32_7B(imm8: i32) { jmpcc32(!test_p(), imm8); } +pub unsafe fn instr32_7C(imm8: i32) { jmpcc32(test_l(), imm8); } +pub unsafe fn instr32_7D(imm8: i32) { jmpcc32(!test_l(), imm8); } +pub unsafe fn instr32_7E(imm8: i32) { jmpcc32(test_le(), imm8); } +pub unsafe fn instr32_7F(imm8: i32) { jmpcc32(!test_le(), imm8); } + +pub unsafe fn instr_80_0_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| add8(x, imm)) } +pub unsafe fn instr_80_0_reg(r1: i32, imm: i32) { write_reg8(r1, add8(read_reg8(r1), imm)); } +pub unsafe fn instr_80_1_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| or8(x, imm)) } +pub unsafe fn instr_80_1_reg(r1: i32, imm: i32) { write_reg8(r1, or8(read_reg8(r1), imm)); } +pub unsafe fn instr_80_2_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| adc8(x, imm)) } +pub unsafe fn instr_80_2_reg(r1: i32, imm: i32) { write_reg8(r1, adc8(read_reg8(r1), imm)); } +pub unsafe fn instr_80_3_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| sbb8(x, imm)) } +pub unsafe fn instr_80_3_reg(r1: i32, imm: i32) { write_reg8(r1, sbb8(read_reg8(r1), imm)); } +pub unsafe fn instr_80_4_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| and8(x, imm)) } +pub unsafe fn instr_80_4_reg(r1: i32, imm: i32) { write_reg8(r1, and8(read_reg8(r1), imm)); } +pub unsafe fn instr_80_5_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| sub8(x, imm)) } +pub unsafe fn instr_80_5_reg(r1: i32, imm: i32) { write_reg8(r1, sub8(read_reg8(r1), imm)); } +pub unsafe fn instr_80_6_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| xor8(x, imm)) } +pub unsafe fn instr_80_6_reg(r1: i32, imm: i32) { write_reg8(r1, xor8(read_reg8(r1), imm)); } +pub unsafe fn instr_80_7_reg(r: i32, imm: i32) { cmp8(read_reg8(r), imm); } +pub unsafe fn instr_80_7_mem(addr: i32, imm: i32) { + cmp8(return_on_pagefault!(safe_read8(addr)), imm); +} +pub unsafe fn instr16_81_0_mem(addr: i32, imm: i32) { safe_read_write16(addr, &|x| add16(x, imm)) } +pub unsafe fn instr16_81_0_reg(r1: i32, imm: i32) { write_reg16(r1, add16(read_reg16(r1), imm)); } +pub unsafe fn instr16_81_1_mem(addr: i32, imm: i32) { safe_read_write16(addr, &|x| or16(x, imm)) } +pub unsafe fn instr16_81_1_reg(r1: i32, imm: i32) { write_reg16(r1, or16(read_reg16(r1), imm)); } +pub unsafe fn instr16_81_2_mem(addr: i32, imm: i32) { safe_read_write16(addr, &|x| adc16(x, imm)) } +pub unsafe fn instr16_81_2_reg(r1: i32, imm: i32) { write_reg16(r1, adc16(read_reg16(r1), imm)); } +pub unsafe fn instr16_81_3_mem(addr: i32, imm: i32) { safe_read_write16(addr, &|x| sbb16(x, imm)) } +pub unsafe fn instr16_81_3_reg(r1: i32, imm: i32) { write_reg16(r1, sbb16(read_reg16(r1), imm)); } +pub unsafe fn instr16_81_4_mem(addr: i32, imm: i32) { safe_read_write16(addr, &|x| and16(x, imm)) } +pub unsafe fn instr16_81_4_reg(r1: i32, imm: i32) { write_reg16(r1, and16(read_reg16(r1), imm)); } +pub unsafe fn instr16_81_5_mem(addr: i32, imm: i32) { safe_read_write16(addr, &|x| sub16(x, imm)) } +pub unsafe fn instr16_81_5_reg(r1: i32, imm: i32) { write_reg16(r1, sub16(read_reg16(r1), imm)); } +pub unsafe fn instr16_81_6_mem(addr: i32, imm: i32) { safe_read_write16(addr, &|x| xor16(x, imm)) } +pub unsafe fn instr16_81_6_reg(r1: i32, imm: i32) { write_reg16(r1, xor16(read_reg16(r1), imm)); } +pub unsafe fn instr16_81_7_reg(r: i32, imm: i32) { cmp16(read_reg16(r), imm); } +pub unsafe fn instr16_81_7_mem(addr: i32, imm: i32) { + cmp16(return_on_pagefault!(safe_read16(addr)), imm); +} +pub unsafe fn instr32_81_0_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| add32(x, imm)) } +pub unsafe fn instr32_81_0_reg(r1: i32, imm: i32) { write_reg32(r1, add32(read_reg32(r1), imm)); } +pub unsafe fn instr32_81_1_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| or32(x, imm)) } +pub unsafe fn instr32_81_1_reg(r1: i32, imm: i32) { write_reg32(r1, or32(read_reg32(r1), imm)); } +pub unsafe fn instr32_81_2_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| adc32(x, imm)) } +pub unsafe fn instr32_81_2_reg(r1: i32, imm: i32) { write_reg32(r1, adc32(read_reg32(r1), imm)); } +pub unsafe fn instr32_81_3_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| sbb32(x, imm)) } +pub unsafe fn instr32_81_3_reg(r1: i32, imm: i32) { write_reg32(r1, sbb32(read_reg32(r1), imm)); } +pub unsafe fn instr32_81_4_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| and32(x, imm)) } +pub unsafe fn instr32_81_4_reg(r1: i32, imm: i32) { write_reg32(r1, and32(read_reg32(r1), imm)); } +pub unsafe fn instr32_81_5_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| sub32(x, imm)) } +pub unsafe fn instr32_81_5_reg(r1: i32, imm: i32) { write_reg32(r1, sub32(read_reg32(r1), imm)); } +pub unsafe fn instr32_81_6_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| xor32(x, imm)) } +pub unsafe fn instr32_81_6_reg(r1: i32, imm: i32) { write_reg32(r1, xor32(read_reg32(r1), imm)); } +pub unsafe fn instr32_81_7_reg(r: i32, imm: i32) { cmp32(read_reg32(r), imm); } +pub unsafe fn instr32_81_7_mem(addr: i32, imm: i32) { + cmp32(return_on_pagefault!(safe_read32s(addr)), imm); +} +pub unsafe fn instr_82_0_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| add8(x, imm)) } +pub unsafe fn instr_82_0_reg(r1: i32, imm: i32) { write_reg8(r1, add8(read_reg8(r1), imm)); } +pub unsafe fn instr_82_1_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| or8(x, imm)) } +pub unsafe fn instr_82_1_reg(r1: i32, imm: i32) { write_reg8(r1, or8(read_reg8(r1), imm)); } +pub unsafe fn instr_82_2_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| adc8(x, imm)) } +pub unsafe fn instr_82_2_reg(r1: i32, imm: i32) { write_reg8(r1, adc8(read_reg8(r1), imm)); } +pub unsafe fn instr_82_3_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| sbb8(x, imm)) } +pub unsafe fn instr_82_3_reg(r1: i32, imm: i32) { write_reg8(r1, sbb8(read_reg8(r1), imm)); } +pub unsafe fn instr_82_4_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| and8(x, imm)) } +pub unsafe fn instr_82_4_reg(r1: i32, imm: i32) { write_reg8(r1, and8(read_reg8(r1), imm)); } +pub unsafe fn instr_82_5_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| sub8(x, imm)) } +pub unsafe fn instr_82_5_reg(r1: i32, imm: i32) { write_reg8(r1, sub8(read_reg8(r1), imm)); } +pub unsafe fn instr_82_6_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| xor8(x, imm)) } +pub unsafe fn instr_82_6_reg(r1: i32, imm: i32) { write_reg8(r1, xor8(read_reg8(r1), imm)); } +pub unsafe fn instr_82_7_reg(r: i32, imm: i32) { cmp8(read_reg8(r), imm); } +pub unsafe fn instr_82_7_mem(addr: i32, imm: i32) { + cmp8(return_on_pagefault!(safe_read8(addr)), imm); +} +pub unsafe fn instr16_83_0_mem(addr: i32, imm: i32) { + safe_read_write16(addr, &|x| add16(x, imm & 0xFFFF)) +} +pub unsafe fn instr16_83_0_reg(r1: i32, imm: i32) { + write_reg16(r1, add16(read_reg16(r1), imm & 0xFFFF)); +} +pub unsafe fn instr16_83_1_mem(addr: i32, imm: i32) { + safe_read_write16(addr, &|x| or16(x, imm & 0xFFFF)) +} +pub unsafe fn instr16_83_1_reg(r1: i32, imm: i32) { + write_reg16(r1, or16(read_reg16(r1), imm & 0xFFFF)); +} +pub unsafe fn instr16_83_2_mem(addr: i32, imm: i32) { + safe_read_write16(addr, &|x| adc16(x, imm & 0xFFFF)) +} +pub unsafe fn instr16_83_2_reg(r1: i32, imm: i32) { + write_reg16(r1, adc16(read_reg16(r1), imm & 0xFFFF)); +} +pub unsafe fn instr16_83_3_mem(addr: i32, imm: i32) { + safe_read_write16(addr, &|x| sbb16(x, imm & 0xFFFF)) +} +pub unsafe fn instr16_83_3_reg(r1: i32, imm: i32) { + write_reg16(r1, sbb16(read_reg16(r1), imm & 0xFFFF)); +} +pub unsafe fn instr16_83_4_mem(addr: i32, imm: i32) { + safe_read_write16(addr, &|x| and16(x, imm & 0xFFFF)) +} +pub unsafe fn instr16_83_4_reg(r1: i32, imm: i32) { + write_reg16(r1, and16(read_reg16(r1), imm & 0xFFFF)); +} +pub unsafe fn instr16_83_5_mem(addr: i32, imm: i32) { + safe_read_write16(addr, &|x| sub16(x, imm & 0xFFFF)) +} +pub unsafe fn instr16_83_5_reg(r1: i32, imm: i32) { + write_reg16(r1, sub16(read_reg16(r1), imm & 0xFFFF)); +} +pub unsafe fn instr16_83_6_mem(addr: i32, imm: i32) { + safe_read_write16(addr, &|x| xor16(x, imm & 0xFFFF)) +} +pub unsafe fn instr16_83_6_reg(r1: i32, imm: i32) { + write_reg16(r1, xor16(read_reg16(r1), imm & 0xFFFF)); +} +pub unsafe fn instr16_83_7_reg(r: i32, imm: i32) { cmp16(read_reg16(r), imm & 0xFFFF); } +pub unsafe fn instr16_83_7_mem(addr: i32, imm: i32) { + cmp16(return_on_pagefault!(safe_read16(addr)), imm & 0xFFFF); +} + +pub unsafe fn instr32_83_0_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| add32(x, imm)) } +pub unsafe fn instr32_83_0_reg(r1: i32, imm: i32) { write_reg32(r1, add32(read_reg32(r1), imm)); } +pub unsafe fn instr32_83_1_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| or32(x, imm)) } +pub unsafe fn instr32_83_1_reg(r1: i32, imm: i32) { write_reg32(r1, or32(read_reg32(r1), imm)); } +pub unsafe fn instr32_83_2_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| adc32(x, imm)) } +pub unsafe fn instr32_83_2_reg(r1: i32, imm: i32) { write_reg32(r1, adc32(read_reg32(r1), imm)); } +pub unsafe fn instr32_83_3_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| sbb32(x, imm)) } +pub unsafe fn instr32_83_3_reg(r1: i32, imm: i32) { write_reg32(r1, sbb32(read_reg32(r1), imm)); } +pub unsafe fn instr32_83_4_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| and32(x, imm)) } +pub unsafe fn instr32_83_4_reg(r1: i32, imm: i32) { write_reg32(r1, and32(read_reg32(r1), imm)); } +pub unsafe fn instr32_83_5_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| sub32(x, imm)) } +pub unsafe fn instr32_83_5_reg(r1: i32, imm: i32) { write_reg32(r1, sub32(read_reg32(r1), imm)); } +pub unsafe fn instr32_83_6_mem(addr: i32, imm: i32) { safe_read_write32(addr, &|x| xor32(x, imm)) } +pub unsafe fn instr32_83_6_reg(r1: i32, imm: i32) { write_reg32(r1, xor32(read_reg32(r1), imm)); } +pub unsafe fn instr32_83_7_reg(r: i32, imm: i32) { cmp32(read_reg32(r), imm); } +pub unsafe fn instr32_83_7_mem(addr: i32, imm: i32) { + cmp32(return_on_pagefault!(safe_read32s(addr)), imm); +} + +pub unsafe fn instr_84_mem(addr: i32, r: i32) { + test8(return_on_pagefault!(safe_read8(addr)), read_reg8(r)); +} +pub unsafe fn instr_84_reg(r1: i32, r: i32) { test8(read_reg8(r1), read_reg8(r)); } +pub unsafe fn instr16_85_mem(addr: i32, r: i32) { + test16(return_on_pagefault!(safe_read16(addr)), read_reg16(r)); +} +pub unsafe fn instr16_85_reg(r1: i32, r: i32) { test16(read_reg16(r1), read_reg16(r)); } +pub unsafe fn instr32_85_mem(addr: i32, r: i32) { + test32(return_on_pagefault!(safe_read32s(addr)), read_reg32(r)); +} +pub unsafe fn instr32_85_reg(r1: i32, r: i32) { test32(read_reg32(r1), read_reg32(r)); } +pub unsafe fn instr_86_mem(addr: i32, r: i32) { safe_read_write8(addr, &|x| xchg8(x, r)) } +pub unsafe fn instr_86_reg(r1: i32, r: i32) { write_reg8(r1, xchg8(read_reg8(r1), r)); } +pub unsafe fn instr16_87_mem(addr: i32, r: i32) { safe_read_write16(addr, &|x| xchg16(x, r)) } +pub unsafe fn instr16_87_reg(r1: i32, r: i32) { write_reg16(r1, xchg16(read_reg16(r1), r)); } +pub unsafe fn instr32_87_mem(addr: i32, r: i32) { safe_read_write32(addr, &|x| xchg32(x, r)) } +pub unsafe fn instr32_87_reg(r1: i32, r: i32) { write_reg32(r1, xchg32(read_reg32(r1), r)); } +pub unsafe fn instr_88_reg(r2: i32, r: i32) { write_reg8(r2, read_reg8(r)); } +pub unsafe fn instr_88_mem(addr: i32, r: i32) { + return_on_pagefault!(safe_write8(addr, read_reg8(r))); +} +pub unsafe fn instr16_89_reg(r2: i32, r: i32) { write_reg16(r2, read_reg16(r)); } +pub unsafe fn instr16_89_mem(addr: i32, r: i32) { + return_on_pagefault!(safe_write16(addr, read_reg16(r))); +} +pub unsafe fn instr32_89_reg(r2: i32, r: i32) { write_reg32(r2, read_reg32(r)); } +pub unsafe fn instr32_89_mem(addr: i32, r: i32) { + return_on_pagefault!(safe_write32(addr, read_reg32(r))); +} +pub unsafe fn instr_8A_mem(addr: i32, r: i32) { + write_reg8(r, return_on_pagefault!(safe_read8(addr))); +} +pub unsafe fn instr_8A_reg(r1: i32, r: i32) { write_reg8(r, read_reg8(r1)); } +pub unsafe fn instr16_8B_mem(addr: i32, r: i32) { + write_reg16(r, return_on_pagefault!(safe_read16(addr))); +} +pub unsafe fn instr16_8B_reg(r1: i32, r: i32) { write_reg16(r, read_reg16(r1)); } +pub unsafe fn instr32_8B_mem(addr: i32, r: i32) { + write_reg32(r, return_on_pagefault!(safe_read32s(addr))); +} +pub unsafe fn instr32_8B_reg(r1: i32, r: i32) { write_reg32(r, read_reg32(r1)); } + +pub unsafe fn instr_8C_check_sreg(seg: i32) -> bool { + if seg >= 6 { + dbg_log!("mov sreg #ud"); + trigger_ud(); + return false; } + else { + return true; + }; +} +pub unsafe fn instr16_8C_reg(r: i32, seg: i32) { + if instr_8C_check_sreg(seg) { + write_reg16(r, *sreg.offset(seg as isize) as i32); + }; +} +pub unsafe fn instr16_8C_mem(addr: i32, seg: i32) { + if instr_8C_check_sreg(seg) { + return_on_pagefault!(safe_write16(addr, *sreg.offset(seg as isize) as i32)); + }; +} +pub unsafe fn instr32_8C_reg(r: i32, seg: i32) { + if instr_8C_check_sreg(seg) { + write_reg32(r, *sreg.offset(seg as isize) as i32); + }; +} +pub unsafe fn instr32_8C_mem(addr: i32, seg: i32) { + if instr_8C_check_sreg(seg) { + return_on_pagefault!(safe_write16(addr, *sreg.offset(seg as isize) as i32)); + }; +} - if(has_66.length || has_F2.length || has_F3.length) - { - const if_blocks = []; +pub unsafe fn instr16_8D_reg(_r: i32, _r2: i32) { + dbg_log!("lea #ud"); + trigger_ud(); +} +pub unsafe fn instr16_8D_mem(modrm_byte: i32, r: i32) { + // lea + *prefixes |= prefix::SEG_PREFIX_ZERO; + if let Ok(addr) = modrm_resolve(modrm_byte) { + write_reg16(r, addr); + } + *prefixes = 0; +} +pub unsafe fn instr32_8D_reg(_r: i32, _r2: i32) { + dbg_log!("lea #ud"); + trigger_ud(); +} +pub unsafe fn instr32_8D_mem(modrm_byte: i32, r: i32) { + // lea + // override prefix, so modrm_resolve does not return the segment part + *prefixes |= prefix::SEG_PREFIX_ZERO; + if let Ok(addr) = modrm_resolve(modrm_byte) { + write_reg32(r, addr); + } + *prefixes = 0; +} - if(has_66.length) { - const body = gen_instruction_body_after_prefix(has_66, size); - if_blocks.push({ condition: "prefixes_ & ::prefix::PREFIX_66 != 0", body, }); - } - if(has_F2.length) { - const body = gen_instruction_body_after_prefix(has_F2, size); - if_blocks.push({ condition: "prefixes_ & ::prefix::PREFIX_F2 != 0", body, }); - } - if(has_F3.length) { - const body = gen_instruction_body_after_prefix(has_F3, size); - if_blocks.push({ condition: "prefixes_ & ::prefix::PREFIX_F3 != 0", body, }); +#[no_mangle] +pub unsafe fn instr_8E_mem(addr: i32, r: i32) { + if r == ES || r == SS || r == DS || r == FS || r == GS { + if !switch_seg(r, return_on_pagefault!(safe_read16(addr))) { + return; } + } + else { + dbg_log!("mov sreg #ud"); + trigger_ud(); + } +} +#[no_mangle] +pub unsafe fn instr_8E_reg(r1: i32, r: i32) { + if r == ES || r == SS || r == DS || r == FS || r == GS { + switch_seg(r, read_reg16(r1)); + } + else { + dbg_log!("mov sreg #ud"); + trigger_ud(); + } +} - const check_prefixes = encoding.sse ? "(::prefix::PREFIX_66 | ::prefix::PREFIX_F2 | ::prefix::PREFIX_F3)" : "(::prefix::PREFIX_F2 | ::prefix::PREFIX_F3)"; - - const else_block = { - body: [].concat( - "dbg_assert!((prefixes_ & " + check_prefixes + ") == 0);", - gen_instruction_body_after_prefix(no_prefix, size) - ) - }; - - return [].concat( - "let prefixes_ = *prefixes;", - code, - { - type: "if-else", - if_blocks, - else_block, - } - ); +pub unsafe fn instr16_8F_0_mem(modrm_byte: i32) { + // pop + // Update esp *before* resolving the address + adjust_stack_reg(2); + match modrm_resolve(modrm_byte) { + Err(()) => { + // a pagefault happened, reset esp + adjust_stack_reg(-2); + }, + Ok(addr) => { + adjust_stack_reg(-2); + let stack_value = return_on_pagefault!(safe_read16(get_stack_pointer(0))); + return_on_pagefault!(safe_write16(addr, stack_value)); + adjust_stack_reg(2); + }, + } +} +pub unsafe fn instr16_8F_0_reg(r: i32) { write_reg16(r, return_on_pagefault!(pop16())); } +pub unsafe fn instr32_8F_0_mem(modrm_byte: i32) { + // Update esp *before* resolving the address + adjust_stack_reg(4); + match modrm_resolve(modrm_byte) { + Err(()) => { + // a pagefault happened, reset esp + adjust_stack_reg(-4); + }, + Ok(addr) => { + adjust_stack_reg(-4); + let stack_value = return_on_pagefault!(safe_read32s(get_stack_pointer(0))); + return_on_pagefault!(safe_write32(addr, stack_value)); + adjust_stack_reg(4); + }, + } +} +pub unsafe fn instr32_8F_0_reg(r: i32) { write_reg32(r, return_on_pagefault!(pop32s())); } + +pub unsafe fn instr_90() {} +pub unsafe fn instr16_91() { xchg16r(CX); } +pub unsafe fn instr32_91() { xchg32r(ECX); } +pub unsafe fn instr16_92() { xchg16r(DX); } +pub unsafe fn instr32_92() { xchg32r(EDX); } +pub unsafe fn instr16_93() { xchg16r(BX); } +pub unsafe fn instr32_93() { xchg32r(EBX); } +pub unsafe fn instr16_94() { xchg16r(SP); } +pub unsafe fn instr32_94() { xchg32r(ESP); } +pub unsafe fn instr16_95() { xchg16r(BP); } +pub unsafe fn instr32_95() { xchg32r(EBP); } +pub unsafe fn instr16_96() { xchg16r(SI); } +pub unsafe fn instr32_96() { xchg32r(ESI); } +pub unsafe fn instr16_97() { xchg16r(DI); } +pub unsafe fn instr32_97() { xchg32r(EDI); } + +pub unsafe fn instr16_98() { write_reg16(AX, read_reg8(AL) << 24 >> 24); } +pub unsafe fn instr32_98() { write_reg32(EAX, read_reg16(AX) as i16 as i32); } +pub unsafe fn instr16_99() { write_reg16(DX, read_reg16(AX) as i16 as i32 >> 15); } +pub unsafe fn instr32_99() { write_reg32(EDX, read_reg32(EAX) >> 31); } + +#[no_mangle] +pub unsafe fn instr16_9A(new_ip: i32, new_cs: i32) { + // callf + far_jump(new_ip, new_cs, true, false); + dbg_assert!(*is_32 || get_real_eip() < 0x10000); +} +#[no_mangle] +pub unsafe fn instr32_9A(new_ip: i32, new_cs: i32) { + if !*protected_mode || vm86_mode() { + if 0 != new_ip as u32 & 0xFFFF0000 { + dbg_assert!(false); + } + } + far_jump(new_ip, new_cs, true, true); + dbg_assert!(*is_32 || get_real_eip() < 0x10000); +} +#[no_mangle] +pub unsafe fn instr_9B() { + // fwait: check for pending fpu exceptions + if *cr & (CR0_MP | CR0_TS) == CR0_MP | CR0_TS { + // Note: Different from task_switch_test + // Triggers when TS and MP bits are set (EM bit is ignored) + trigger_nm(); + } + else { + fwait(); + }; +} +unsafe fn instr_pushf_popf_check() -> bool { 0 != *flags & FLAG_VM && getiopl() < 3 } +pub unsafe fn instr16_9C() { + // pushf + if instr_pushf_popf_check() { + dbg_assert!(*protected_mode); + dbg_log!("pushf #gp"); + trigger_gp(0); } else { - return [].concat( - code, - gen_instruction_body_after_prefix(encodings, size) - ); + return_on_pagefault!(push16(get_eflags())); + }; +} +pub unsafe fn instr32_9C() { + // pushf + if instr_pushf_popf_check() { + // trap to virtual 8086 monitor + dbg_assert!(*protected_mode); + dbg_log!("pushf #gp"); + trigger_gp(0); + } + else { + // vm and rf flag are cleared in image stored on the stack + return_on_pagefault!(push32(get_eflags() & 0xFCFFFF)); + }; +} + +pub unsafe fn instr16_9D() { + // popf + if instr_pushf_popf_check() { + dbg_log!("popf #gp"); + trigger_gp(0); + return; + } + let old_eflags = *flags; + update_eflags(*flags & !0xFFFF | return_on_pagefault!(pop16())); + if old_eflags & FLAG_INTERRUPT == 0 && *flags & FLAG_INTERRUPT != 0 { + handle_irqs(); + } +} +pub unsafe fn instr32_9D() { + // popf + if instr_pushf_popf_check() { + dbg_log!("popf #gp"); + trigger_gp(0); + return; + } + let old_eflags = *flags; + update_eflags(return_on_pagefault!(pop32s())); + if old_eflags & FLAG_INTERRUPT == 0 && *flags & FLAG_INTERRUPT != 0 { + handle_irqs(); } } -function gen_instruction_body_after_prefix(encodings, size) -{ - const encoding = encodings[0]; +pub unsafe fn instr_9E() { + // sahf + *flags = *flags & !255 | read_reg8(AH); + *flags = *flags & FLAGS_MASK | FLAGS_DEFAULT; + *flags_changed &= !255; +} +pub unsafe fn instr_9F() { + // lahf + write_reg8(AH, get_eflags()); +} - if(encoding.fixed_g !== undefined) - { - assert(encoding.e); - - // instruction with modrm byte where the middle 3 bits encode the instruction - - // group by opcode without prefix plus middle bits of modrm byte - let cases = encodings.reduce((cases_by_opcode, case_) => { - assert(typeof case_.fixed_g === "number"); - cases_by_opcode[case_.opcode & 0xFFFF | case_.fixed_g << 16] = case_; - return cases_by_opcode; - }, Object.create(null)); - cases = Object.values(cases).sort((e1, e2) => e1.fixed_g - e2.fixed_g); - - return [ - { - type: "switch", - condition: "modrm_byte >> 3 & 7", - cases: cases.map(case_ => { - const fixed_g = case_.fixed_g; - const body = gen_instruction_body_after_fixed_g(case_, size); - - return { - conditions: [fixed_g], - body, - }; - }), - - default_case: { - body: [ - `if DEBUG { panic!("Bad instruction at {:x}", *instruction_pointer); }`, - "trigger_ud();", - ], - } - }, - ]; +pub unsafe fn instr_A0(moffs: i32) { + // mov + let data = return_on_pagefault!(safe_read8(return_on_pagefault!(get_seg_prefix_ds(moffs)))); + write_reg8(AL, data); +} +pub unsafe fn instr16_A1(moffs: i32) { + // mov + let data = return_on_pagefault!(safe_read16(return_on_pagefault!(get_seg_prefix_ds(moffs)))); + write_reg16(AX, data); +} +pub unsafe fn instr32_A1(moffs: i32) { + let data = return_on_pagefault!(safe_read32s(return_on_pagefault!(get_seg_prefix_ds(moffs)))); + write_reg32(EAX, data); +} +pub unsafe fn instr_A2(moffs: i32) { + // mov + return_on_pagefault!(safe_write8( + return_on_pagefault!(get_seg_prefix_ds(moffs)), + read_reg8(AL) + )); +} +pub unsafe fn instr16_A3(moffs: i32) { + // mov + return_on_pagefault!(safe_write16( + return_on_pagefault!(get_seg_prefix_ds(moffs)), + read_reg16(AX) + )); +} +pub unsafe fn instr32_A3(moffs: i32) { + return_on_pagefault!(safe_write32( + return_on_pagefault!(get_seg_prefix_ds(moffs)), + read_reg32(EAX) + )); +} + +pub unsafe fn instr_A4() { movsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } +pub unsafe fn instr_F2A4() { movsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } +pub unsafe fn instr_F3A4() { movsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } + +pub unsafe fn instr16_A5() { + movsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); +} +pub unsafe fn instr32_A5() { + movsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); +} +pub unsafe fn instr16_F2A5() { movsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } +pub unsafe fn instr16_F3A5() { movsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } +pub unsafe fn instr32_F2A5() { movsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } +pub unsafe fn instr32_F3A5() { movsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } + +pub unsafe fn instr_A6() { cmpsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } +pub unsafe fn instr_F2A6() { cmpsb_repnz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } +pub unsafe fn instr_F3A6() { cmpsb_repz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } +pub unsafe fn instr16_A7() { + cmpsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); +} +pub unsafe fn instr32_A7() { + cmpsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); +} +pub unsafe fn instr16_F2A7() { + cmpsw_repnz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); +} +pub unsafe fn instr16_F3A7() { + cmpsw_repz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); +} +pub unsafe fn instr32_F2A7() { + cmpsd_repnz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); +} +pub unsafe fn instr32_F3A7() { + cmpsd_repz(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); +} + +pub unsafe fn instr_A8(imm8: i32) { test8(read_reg8(AL), imm8); } +pub unsafe fn instr16_A9(imm16: i32) { test16(read_reg16(AX), imm16); } +pub unsafe fn instr32_A9(imm32: i32) { test32(read_reg32(EAX), imm32); } + +pub unsafe fn instr_AA() { stosb_no_rep(is_asize_32()); } +pub unsafe fn instr_F2AA() { stosb_rep(is_asize_32()); } +pub unsafe fn instr_F3AA() { stosb_rep(is_asize_32()); } + +pub unsafe fn instr16_AB() { stosw_no_rep(is_asize_32()); } +pub unsafe fn instr32_AB() { stosd_no_rep(is_asize_32()); } +pub unsafe fn instr16_F2AB() { stosw_rep(is_asize_32()); } +pub unsafe fn instr16_F3AB() { stosw_rep(is_asize_32()); } +pub unsafe fn instr32_F2AB() { stosd_rep(is_asize_32()); } +pub unsafe fn instr32_F3AB() { stosd_rep(is_asize_32()); } + +pub unsafe fn instr_AC() { lodsb_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } +pub unsafe fn instr_F2AC() { lodsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } +pub unsafe fn instr_F3AC() { lodsb_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } + +pub unsafe fn instr16_AD() { + lodsw_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); +} +pub unsafe fn instr32_AD() { + lodsd_no_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); +} +pub unsafe fn instr16_F2AD() { lodsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } +pub unsafe fn instr16_F3AD() { lodsw_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } +pub unsafe fn instr32_F2AD() { lodsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } +pub unsafe fn instr32_F3AD() { lodsd_rep(is_asize_32(), return_on_pagefault!(get_seg_prefix(DS))); } + +pub unsafe fn instr_AE() { scasb_no_rep(is_asize_32()); } +pub unsafe fn instr_F2AE() { scasb_repnz(is_asize_32()); } +pub unsafe fn instr_F3AE() { scasb_repz(is_asize_32()); } + +pub unsafe fn instr16_AF() { scasw_no_rep(is_asize_32()); } +pub unsafe fn instr32_AF() { scasd_no_rep(is_asize_32()); } +pub unsafe fn instr16_F2AF() { scasw_repnz(is_asize_32()); } +pub unsafe fn instr16_F3AF() { scasw_repz(is_asize_32()); } +pub unsafe fn instr32_F2AF() { scasd_repnz(is_asize_32()); } +pub unsafe fn instr32_F3AF() { scasd_repz(is_asize_32()); } + +pub unsafe fn instr_B0(imm8: i32) { write_reg8(AL, imm8); } +pub unsafe fn instr_B1(imm8: i32) { write_reg8(CL, imm8); } +pub unsafe fn instr_B2(imm8: i32) { write_reg8(DL, imm8); } +pub unsafe fn instr_B3(imm8: i32) { write_reg8(BL, imm8); } +pub unsafe fn instr_B4(imm8: i32) { write_reg8(AH, imm8); } +pub unsafe fn instr_B5(imm8: i32) { write_reg8(CH, imm8); } +pub unsafe fn instr_B6(imm8: i32) { write_reg8(DH, imm8); } +pub unsafe fn instr_B7(imm8: i32) { write_reg8(BH, imm8); } +pub unsafe fn instr16_B8(imm: i32) { write_reg16(AX, imm); } +pub unsafe fn instr32_B8(imm: i32) { write_reg32(EAX, imm); } +pub unsafe fn instr16_B9(imm: i32) { write_reg16(CX, imm); } +pub unsafe fn instr32_B9(imm: i32) { write_reg32(ECX, imm); } +pub unsafe fn instr16_BA(imm: i32) { write_reg16(DX, imm); } +pub unsafe fn instr32_BA(imm: i32) { write_reg32(EDX, imm); } +pub unsafe fn instr16_BB(imm: i32) { write_reg16(BX, imm); } +pub unsafe fn instr32_BB(imm: i32) { write_reg32(EBX, imm); } +pub unsafe fn instr16_BC(imm: i32) { write_reg16(SP, imm); } +pub unsafe fn instr32_BC(imm: i32) { write_reg32(ESP, imm); } +pub unsafe fn instr16_BD(imm: i32) { write_reg16(BP, imm); } +pub unsafe fn instr32_BD(imm: i32) { write_reg32(EBP, imm); } +pub unsafe fn instr16_BE(imm: i32) { write_reg16(SI, imm); } +pub unsafe fn instr32_BE(imm: i32) { write_reg32(ESI, imm); } +pub unsafe fn instr16_BF(imm: i32) { write_reg16(DI, imm); } +pub unsafe fn instr32_BF(imm: i32) { write_reg32(EDI, imm); } + +pub unsafe fn instr_C0_0_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| rol8(x, imm & 31)) } +pub unsafe fn instr_C0_0_reg(r1: i32, imm: i32) { write_reg8(r1, rol8(read_reg8(r1), imm & 31)); } +pub unsafe fn instr_C0_1_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| ror8(x, imm & 31)) } +pub unsafe fn instr_C0_1_reg(r1: i32, imm: i32) { write_reg8(r1, ror8(read_reg8(r1), imm & 31)); } +pub unsafe fn instr_C0_2_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| rcl8(x, imm & 31)) } +pub unsafe fn instr_C0_2_reg(r1: i32, imm: i32) { write_reg8(r1, rcl8(read_reg8(r1), imm & 31)); } +pub unsafe fn instr_C0_3_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| rcr8(x, imm & 31)) } +pub unsafe fn instr_C0_3_reg(r1: i32, imm: i32) { write_reg8(r1, rcr8(read_reg8(r1), imm & 31)); } +pub unsafe fn instr_C0_4_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| shl8(x, imm & 31)) } +pub unsafe fn instr_C0_4_reg(r1: i32, imm: i32) { write_reg8(r1, shl8(read_reg8(r1), imm & 31)); } +pub unsafe fn instr_C0_5_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| shr8(x, imm & 31)) } +pub unsafe fn instr_C0_5_reg(r1: i32, imm: i32) { write_reg8(r1, shr8(read_reg8(r1), imm & 31)); } +pub unsafe fn instr_C0_6_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| shl8(x, imm & 31)) } +pub unsafe fn instr_C0_6_reg(r1: i32, imm: i32) { write_reg8(r1, shl8(read_reg8(r1), imm & 31)); } +pub unsafe fn instr_C0_7_mem(addr: i32, imm: i32) { safe_read_write8(addr, &|x| sar8(x, imm & 31)) } +pub unsafe fn instr_C0_7_reg(r1: i32, imm: i32) { write_reg8(r1, sar8(read_reg8(r1), imm & 31)); } +pub unsafe fn instr16_C1_0_mem(addr: i32, imm: i32) { + safe_read_write16(addr, &|x| rol16(x, imm & 31)) +} +pub unsafe fn instr16_C1_0_reg(r1: i32, imm: i32) { + write_reg16(r1, rol16(read_reg16(r1), imm & 31)); +} +pub unsafe fn instr16_C1_1_mem(addr: i32, imm: i32) { + safe_read_write16(addr, &|x| ror16(x, imm & 31)) +} +pub unsafe fn instr16_C1_1_reg(r1: i32, imm: i32) { + write_reg16(r1, ror16(read_reg16(r1), imm & 31)); +} +pub unsafe fn instr16_C1_2_mem(addr: i32, imm: i32) { + safe_read_write16(addr, &|x| rcl16(x, imm & 31)) +} +pub unsafe fn instr16_C1_2_reg(r1: i32, imm: i32) { + write_reg16(r1, rcl16(read_reg16(r1), imm & 31)); +} +pub unsafe fn instr16_C1_3_mem(addr: i32, imm: i32) { + safe_read_write16(addr, &|x| rcr16(x, imm & 31)) +} +pub unsafe fn instr16_C1_3_reg(r1: i32, imm: i32) { + write_reg16(r1, rcr16(read_reg16(r1), imm & 31)); +} +pub unsafe fn instr16_C1_4_mem(addr: i32, imm: i32) { + safe_read_write16(addr, &|x| shl16(x, imm & 31)) +} +pub unsafe fn instr16_C1_4_reg(r1: i32, imm: i32) { + write_reg16(r1, shl16(read_reg16(r1), imm & 31)); +} +pub unsafe fn instr16_C1_5_mem(addr: i32, imm: i32) { + safe_read_write16(addr, &|x| shr16(x, imm & 31)) +} +pub unsafe fn instr16_C1_5_reg(r1: i32, imm: i32) { + write_reg16(r1, shr16(read_reg16(r1), imm & 31)); +} +pub unsafe fn instr16_C1_6_mem(addr: i32, imm: i32) { + safe_read_write16(addr, &|x| shl16(x, imm & 31)) +} +pub unsafe fn instr16_C1_6_reg(r1: i32, imm: i32) { + write_reg16(r1, shl16(read_reg16(r1), imm & 31)); +} +pub unsafe fn instr16_C1_7_mem(addr: i32, imm: i32) { + safe_read_write16(addr, &|x| sar16(x, imm & 31)) +} +pub unsafe fn instr16_C1_7_reg(r1: i32, imm: i32) { + write_reg16(r1, sar16(read_reg16(r1), imm & 31)); +} +pub unsafe fn instr32_C1_0_mem(addr: i32, imm: i32) { + safe_read_write32(addr, &|x| rol32(x, imm & 31)) +} +pub unsafe fn instr32_C1_0_reg(r1: i32, imm: i32) { + write_reg32(r1, rol32(read_reg32(r1), imm & 31)); +} +pub unsafe fn instr32_C1_1_mem(addr: i32, imm: i32) { + safe_read_write32(addr, &|x| ror32(x, imm & 31)) +} +pub unsafe fn instr32_C1_1_reg(r1: i32, imm: i32) { + write_reg32(r1, ror32(read_reg32(r1), imm & 31)); +} +pub unsafe fn instr32_C1_2_mem(addr: i32, imm: i32) { + safe_read_write32(addr, &|x| rcl32(x, imm & 31)) +} +pub unsafe fn instr32_C1_2_reg(r1: i32, imm: i32) { + write_reg32(r1, rcl32(read_reg32(r1), imm & 31)); +} +pub unsafe fn instr32_C1_3_mem(addr: i32, imm: i32) { + safe_read_write32(addr, &|x| rcr32(x, imm & 31)) +} +pub unsafe fn instr32_C1_3_reg(r1: i32, imm: i32) { + write_reg32(r1, rcr32(read_reg32(r1), imm & 31)); +} +pub unsafe fn instr32_C1_4_mem(addr: i32, imm: i32) { + safe_read_write32(addr, &|x| shl32(x, imm & 31)) +} +pub unsafe fn instr32_C1_4_reg(r1: i32, imm: i32) { + write_reg32(r1, shl32(read_reg32(r1), imm & 31)); +} +pub unsafe fn instr32_C1_5_mem(addr: i32, imm: i32) { + safe_read_write32(addr, &|x| shr32(x, imm & 31)) +} +pub unsafe fn instr32_C1_5_reg(r1: i32, imm: i32) { + write_reg32(r1, shr32(read_reg32(r1), imm & 31)); +} +pub unsafe fn instr32_C1_6_mem(addr: i32, imm: i32) { + safe_read_write32(addr, &|x| shl32(x, imm & 31)) +} +pub unsafe fn instr32_C1_6_reg(r1: i32, imm: i32) { + write_reg32(r1, shl32(read_reg32(r1), imm & 31)); +} +pub unsafe fn instr32_C1_7_mem(addr: i32, imm: i32) { + safe_read_write32(addr, &|x| sar32(x, imm & 31)) +} +pub unsafe fn instr32_C1_7_reg(r1: i32, imm: i32) { + write_reg32(r1, sar32(read_reg32(r1), imm & 31)); +} + +pub unsafe fn instr16_C2(imm16: i32) { + // retn + let cs = get_seg_cs(); + *instruction_pointer = cs + return_on_pagefault!(pop16()); + dbg_assert!(*is_32 || get_real_eip() < 0x10000); + adjust_stack_reg(imm16); +} +pub unsafe fn instr32_C2(imm16: i32) { + // retn + let cs = get_seg_cs(); + let ip = return_on_pagefault!(pop32s()); + dbg_assert!(*is_32 || ip < 0x10000); + *instruction_pointer = cs + ip; + adjust_stack_reg(imm16); +} +pub unsafe fn instr16_C3() { + // retn + let cs = get_seg_cs(); + *instruction_pointer = cs + return_on_pagefault!(pop16()); +} +pub unsafe fn instr32_C3() { + // retn + let cs = get_seg_cs(); + let ip = return_on_pagefault!(pop32s()); + dbg_assert!(*is_32 || ip < 0x10000); + *instruction_pointer = cs + ip; +} + +#[no_mangle] +pub unsafe fn instr16_C4_reg(_unused1: i32, _unused2: i32) { trigger_ud(); } +#[no_mangle] +pub unsafe fn instr16_C4_mem(addr: i32, r: i32) { lss16(addr, r, ES); } +#[no_mangle] +pub unsafe fn instr32_C4_reg(_unused1: i32, _unused2: i32) { trigger_ud(); } +#[no_mangle] +pub unsafe fn instr32_C4_mem(addr: i32, r: i32) { lss32(addr, r, ES); } +#[no_mangle] +pub unsafe fn instr16_C5_reg(_unused1: i32, _unused2: i32) { trigger_ud(); } +#[no_mangle] +pub unsafe fn instr16_C5_mem(addr: i32, r: i32) { lss16(addr, r, DS); } +#[no_mangle] +pub unsafe fn instr32_C5_reg(_unused1: i32, _unused2: i32) { trigger_ud(); } +#[no_mangle] +pub unsafe fn instr32_C5_mem(addr: i32, r: i32) { lss32(addr, r, DS); } + +pub unsafe fn instr_C6_0_reg(r: i32, imm: i32) { write_reg8(r, imm); } +pub unsafe fn instr_C6_0_mem(addr: i32, imm: i32) { + return_on_pagefault!(safe_write8(addr, imm)); +} +pub unsafe fn instr16_C7_0_reg(r: i32, imm: i32) { write_reg16(r, imm); } +pub unsafe fn instr16_C7_0_mem(addr: i32, imm: i32) { + return_on_pagefault!(safe_write16(addr, imm)); +} +pub unsafe fn instr32_C7_0_reg(r: i32, imm: i32) { write_reg32(r, imm); } +pub unsafe fn instr32_C7_0_mem(addr: i32, imm: i32) { + return_on_pagefault!(safe_write32(addr, imm)); +} + +#[no_mangle] +pub unsafe fn instr16_C8(size: i32, nesting: i32) { enter16(size, nesting); } +#[no_mangle] +pub unsafe fn instr32_C8(size: i32, nesting: i32) { enter32(size, nesting); } + +pub unsafe fn instr16_C9() { + // leave + let old_vbp = if *stack_size_32 { read_reg32(EBP) } else { read_reg16(BP) }; + let new_bp = return_on_pagefault!(safe_read16(get_seg_ss() + old_vbp)); + set_stack_reg(old_vbp + 2); + write_reg16(BP, new_bp); +} +pub unsafe fn instr32_C9() { + let old_vbp = if *stack_size_32 { read_reg32(EBP) } else { read_reg16(BP) }; + let new_ebp = return_on_pagefault!(safe_read32s(get_seg_ss() + old_vbp)); + set_stack_reg(old_vbp + 4); + write_reg32(EBP, new_ebp); +} +#[no_mangle] +pub unsafe fn instr16_CA(imm16: i32) { + // retf + let ip = return_on_pagefault!(safe_read16(get_stack_pointer(0))); + let cs = return_on_pagefault!(safe_read16(get_stack_pointer(2))); + far_return(ip, cs, imm16, false); +} +#[no_mangle] +pub unsafe fn instr32_CA(imm16: i32) { + // retf + let ip = return_on_pagefault!(safe_read32s(get_stack_pointer(0))); + let cs = return_on_pagefault!(safe_read32s(get_stack_pointer(4))) & 0xFFFF; + far_return(ip, cs, imm16, true); + dbg_assert!(*is_32 || get_real_eip() < 0x10000); +} +#[no_mangle] +pub unsafe fn instr16_CB() { + // retf + let ip = return_on_pagefault!(safe_read16(get_stack_pointer(0))); + let cs = return_on_pagefault!(safe_read16(get_stack_pointer(2))); + far_return(ip, cs, 0, false); + dbg_assert!(*is_32 || get_real_eip() < 0x10000); +} +#[no_mangle] +pub unsafe fn instr32_CB() { + // retf + let ip = return_on_pagefault!(safe_read32s(get_stack_pointer(0))); + let cs = return_on_pagefault!(safe_read32s(get_stack_pointer(4))) & 0xFFFF; + far_return(ip, cs, 0, true); + dbg_assert!(*is_32 || get_real_eip() < 0x10000); +} +#[no_mangle] +pub unsafe fn instr_CC() { + // INT3 + // TODO: inhibit iopl checks + dbg_log!("INT3"); + call_interrupt_vector(3, true, None); +} +#[no_mangle] +pub unsafe fn instr_CD(imm8: i32) { + // INT + call_interrupt_vector(imm8, true, None); +} +#[no_mangle] +pub unsafe fn instr_CE() { + // INTO + dbg_log!("INTO"); + if getof() { + // TODO: inhibit iopl checks + call_interrupt_vector(CPU_EXCEPTION_OF, true, None); + }; +} +#[no_mangle] +pub unsafe fn instr16_CF() { + // iret + iret16(); +} +#[no_mangle] +pub unsafe fn instr32_CF() { iret32(); } + +pub unsafe fn instr_D0_0_mem(addr: i32) { safe_read_write8(addr, &|x| rol8(x, 1)) } +pub unsafe fn instr_D0_0_reg(r1: i32) { write_reg8(r1, rol8(read_reg8(r1), 1)); } +pub unsafe fn instr_D0_1_mem(addr: i32) { safe_read_write8(addr, &|x| ror8(x, 1)) } +pub unsafe fn instr_D0_1_reg(r1: i32) { write_reg8(r1, ror8(read_reg8(r1), 1)); } +pub unsafe fn instr_D0_2_mem(addr: i32) { safe_read_write8(addr, &|x| rcl8(x, 1)) } +pub unsafe fn instr_D0_2_reg(r1: i32) { write_reg8(r1, rcl8(read_reg8(r1), 1)); } +pub unsafe fn instr_D0_3_mem(addr: i32) { safe_read_write8(addr, &|x| rcr8(x, 1)) } +pub unsafe fn instr_D0_3_reg(r1: i32) { write_reg8(r1, rcr8(read_reg8(r1), 1)); } +pub unsafe fn instr_D0_4_mem(addr: i32) { safe_read_write8(addr, &|x| shl8(x, 1)) } +pub unsafe fn instr_D0_4_reg(r1: i32) { write_reg8(r1, shl8(read_reg8(r1), 1)); } +pub unsafe fn instr_D0_5_mem(addr: i32) { safe_read_write8(addr, &|x| shr8(x, 1)) } +pub unsafe fn instr_D0_5_reg(r1: i32) { write_reg8(r1, shr8(read_reg8(r1), 1)); } +pub unsafe fn instr_D0_6_mem(addr: i32) { safe_read_write8(addr, &|x| shl8(x, 1)) } +pub unsafe fn instr_D0_6_reg(r1: i32) { write_reg8(r1, shl8(read_reg8(r1), 1)); } +pub unsafe fn instr_D0_7_mem(addr: i32) { safe_read_write8(addr, &|x| sar8(x, 1)) } +pub unsafe fn instr_D0_7_reg(r1: i32) { write_reg8(r1, sar8(read_reg8(r1), 1)); } +pub unsafe fn instr16_D1_0_mem(addr: i32) { safe_read_write16(addr, &|x| rol16(x, 1)) } +pub unsafe fn instr16_D1_0_reg(r1: i32) { write_reg16(r1, rol16(read_reg16(r1), 1)); } +pub unsafe fn instr16_D1_1_mem(addr: i32) { safe_read_write16(addr, &|x| ror16(x, 1)) } +pub unsafe fn instr16_D1_1_reg(r1: i32) { write_reg16(r1, ror16(read_reg16(r1), 1)); } +pub unsafe fn instr16_D1_2_mem(addr: i32) { safe_read_write16(addr, &|x| rcl16(x, 1)) } +pub unsafe fn instr16_D1_2_reg(r1: i32) { write_reg16(r1, rcl16(read_reg16(r1), 1)); } +pub unsafe fn instr16_D1_3_mem(addr: i32) { safe_read_write16(addr, &|x| rcr16(x, 1)) } +pub unsafe fn instr16_D1_3_reg(r1: i32) { write_reg16(r1, rcr16(read_reg16(r1), 1)); } +pub unsafe fn instr16_D1_4_mem(addr: i32) { safe_read_write16(addr, &|x| shl16(x, 1)) } +pub unsafe fn instr16_D1_4_reg(r1: i32) { write_reg16(r1, shl16(read_reg16(r1), 1)); } +pub unsafe fn instr16_D1_5_mem(addr: i32) { safe_read_write16(addr, &|x| shr16(x, 1)) } +pub unsafe fn instr16_D1_5_reg(r1: i32) { write_reg16(r1, shr16(read_reg16(r1), 1)); } +pub unsafe fn instr16_D1_6_mem(addr: i32) { safe_read_write16(addr, &|x| shl16(x, 1)) } +pub unsafe fn instr16_D1_6_reg(r1: i32) { write_reg16(r1, shl16(read_reg16(r1), 1)); } +pub unsafe fn instr16_D1_7_mem(addr: i32) { safe_read_write16(addr, &|x| sar16(x, 1)) } +pub unsafe fn instr16_D1_7_reg(r1: i32) { write_reg16(r1, sar16(read_reg16(r1), 1)); } +pub unsafe fn instr32_D1_0_mem(addr: i32) { safe_read_write32(addr, &|x| rol32(x, 1)) } +pub unsafe fn instr32_D1_0_reg(r1: i32) { write_reg32(r1, rol32(read_reg32(r1), 1)); } +pub unsafe fn instr32_D1_1_mem(addr: i32) { safe_read_write32(addr, &|x| ror32(x, 1)) } +pub unsafe fn instr32_D1_1_reg(r1: i32) { write_reg32(r1, ror32(read_reg32(r1), 1)); } +pub unsafe fn instr32_D1_2_mem(addr: i32) { safe_read_write32(addr, &|x| rcl32(x, 1)) } +pub unsafe fn instr32_D1_2_reg(r1: i32) { write_reg32(r1, rcl32(read_reg32(r1), 1)); } +pub unsafe fn instr32_D1_3_mem(addr: i32) { safe_read_write32(addr, &|x| rcr32(x, 1)) } +pub unsafe fn instr32_D1_3_reg(r1: i32) { write_reg32(r1, rcr32(read_reg32(r1), 1)); } +pub unsafe fn instr32_D1_4_mem(addr: i32) { safe_read_write32(addr, &|x| shl32(x, 1)) } +pub unsafe fn instr32_D1_4_reg(r1: i32) { write_reg32(r1, shl32(read_reg32(r1), 1)); } +pub unsafe fn instr32_D1_5_mem(addr: i32) { safe_read_write32(addr, &|x| shr32(x, 1)) } +pub unsafe fn instr32_D1_5_reg(r1: i32) { write_reg32(r1, shr32(read_reg32(r1), 1)); } +pub unsafe fn instr32_D1_6_mem(addr: i32) { safe_read_write32(addr, &|x| shl32(x, 1)) } +pub unsafe fn instr32_D1_6_reg(r1: i32) { write_reg32(r1, shl32(read_reg32(r1), 1)); } +pub unsafe fn instr32_D1_7_mem(addr: i32) { safe_read_write32(addr, &|x| sar32(x, 1)) } +pub unsafe fn instr32_D1_7_reg(r1: i32) { write_reg32(r1, sar32(read_reg32(r1), 1)); } +pub unsafe fn instr_D2_0_mem(addr: i32) { safe_read_write8(addr, &|x| rol8(x, read_reg8(CL) & 31)) } +pub unsafe fn instr_D2_0_reg(r1: i32) { write_reg8(r1, rol8(read_reg8(r1), read_reg8(CL) & 31)); } +pub unsafe fn instr_D2_1_mem(addr: i32) { safe_read_write8(addr, &|x| ror8(x, read_reg8(CL) & 31)) } +pub unsafe fn instr_D2_1_reg(r1: i32) { write_reg8(r1, ror8(read_reg8(r1), read_reg8(CL) & 31)); } +pub unsafe fn instr_D2_2_mem(addr: i32) { safe_read_write8(addr, &|x| rcl8(x, read_reg8(CL) & 31)) } +pub unsafe fn instr_D2_2_reg(r1: i32) { write_reg8(r1, rcl8(read_reg8(r1), read_reg8(CL) & 31)); } +pub unsafe fn instr_D2_3_mem(addr: i32) { safe_read_write8(addr, &|x| rcr8(x, read_reg8(CL) & 31)) } +pub unsafe fn instr_D2_3_reg(r1: i32) { write_reg8(r1, rcr8(read_reg8(r1), read_reg8(CL) & 31)); } +pub unsafe fn instr_D2_4_mem(addr: i32) { safe_read_write8(addr, &|x| shl8(x, read_reg8(CL) & 31)) } +pub unsafe fn instr_D2_4_reg(r1: i32) { write_reg8(r1, shl8(read_reg8(r1), read_reg8(CL) & 31)); } +pub unsafe fn instr_D2_5_mem(addr: i32) { safe_read_write8(addr, &|x| shr8(x, read_reg8(CL) & 31)) } +pub unsafe fn instr_D2_5_reg(r1: i32) { write_reg8(r1, shr8(read_reg8(r1), read_reg8(CL) & 31)); } +pub unsafe fn instr_D2_6_mem(addr: i32) { safe_read_write8(addr, &|x| shl8(x, read_reg8(CL) & 31)) } +pub unsafe fn instr_D2_6_reg(r1: i32) { write_reg8(r1, shl8(read_reg8(r1), read_reg8(CL) & 31)); } +pub unsafe fn instr_D2_7_mem(addr: i32) { safe_read_write8(addr, &|x| sar8(x, read_reg8(CL) & 31)) } +pub unsafe fn instr_D2_7_reg(r1: i32) { write_reg8(r1, sar8(read_reg8(r1), read_reg8(CL) & 31)); } +pub unsafe fn instr16_D3_0_mem(addr: i32) { + safe_read_write16(addr, &|x| rol16(x, read_reg8(CL) & 31)) +} +pub unsafe fn instr16_D3_0_reg(r1: i32) { + write_reg16(r1, rol16(read_reg16(r1), read_reg8(CL) & 31)); +} +pub unsafe fn instr16_D3_1_mem(addr: i32) { + safe_read_write16(addr, &|x| ror16(x, read_reg8(CL) & 31)) +} +pub unsafe fn instr16_D3_1_reg(r1: i32) { + write_reg16(r1, ror16(read_reg16(r1), read_reg8(CL) & 31)); +} +pub unsafe fn instr16_D3_2_mem(addr: i32) { + safe_read_write16(addr, &|x| rcl16(x, read_reg8(CL) & 31)) +} +pub unsafe fn instr16_D3_2_reg(r1: i32) { + write_reg16(r1, rcl16(read_reg16(r1), read_reg8(CL) & 31)); +} +pub unsafe fn instr16_D3_3_mem(addr: i32) { + safe_read_write16(addr, &|x| rcr16(x, read_reg8(CL) & 31)) +} +pub unsafe fn instr16_D3_3_reg(r1: i32) { + write_reg16(r1, rcr16(read_reg16(r1), read_reg8(CL) & 31)); +} +pub unsafe fn instr16_D3_4_mem(addr: i32) { + safe_read_write16(addr, &|x| shl16(x, read_reg8(CL) & 31)) +} +pub unsafe fn instr16_D3_4_reg(r1: i32) { + write_reg16(r1, shl16(read_reg16(r1), read_reg8(CL) & 31)); +} +pub unsafe fn instr16_D3_5_mem(addr: i32) { + safe_read_write16(addr, &|x| shr16(x, read_reg8(CL) & 31)) +} +pub unsafe fn instr16_D3_5_reg(r1: i32) { + write_reg16(r1, shr16(read_reg16(r1), read_reg8(CL) & 31)); +} +pub unsafe fn instr16_D3_6_mem(addr: i32) { + safe_read_write16(addr, &|x| shl16(x, read_reg8(CL) & 31)) +} +pub unsafe fn instr16_D3_6_reg(r1: i32) { + write_reg16(r1, shl16(read_reg16(r1), read_reg8(CL) & 31)); +} +pub unsafe fn instr16_D3_7_mem(addr: i32) { + safe_read_write16(addr, &|x| sar16(x, read_reg8(CL) & 31)) +} +pub unsafe fn instr16_D3_7_reg(r1: i32) { + write_reg16(r1, sar16(read_reg16(r1), read_reg8(CL) & 31)); +} +pub unsafe fn instr32_D3_0_mem(addr: i32) { + safe_read_write32(addr, &|x| rol32(x, read_reg8(CL) & 31)) +} +pub unsafe fn instr32_D3_0_reg(r1: i32) { + write_reg32(r1, rol32(read_reg32(r1), read_reg8(CL) & 31)); +} +pub unsafe fn instr32_D3_1_mem(addr: i32) { + safe_read_write32(addr, &|x| ror32(x, read_reg8(CL) & 31)) +} +pub unsafe fn instr32_D3_1_reg(r1: i32) { + write_reg32(r1, ror32(read_reg32(r1), read_reg8(CL) & 31)); +} +pub unsafe fn instr32_D3_2_mem(addr: i32) { + safe_read_write32(addr, &|x| rcl32(x, read_reg8(CL) & 31)) +} +pub unsafe fn instr32_D3_2_reg(r1: i32) { + write_reg32(r1, rcl32(read_reg32(r1), read_reg8(CL) & 31)); +} +pub unsafe fn instr32_D3_3_mem(addr: i32) { + safe_read_write32(addr, &|x| rcr32(x, read_reg8(CL) & 31)) +} +pub unsafe fn instr32_D3_3_reg(r1: i32) { + write_reg32(r1, rcr32(read_reg32(r1), read_reg8(CL) & 31)); +} +pub unsafe fn instr32_D3_4_mem(addr: i32) { + safe_read_write32(addr, &|x| shl32(x, read_reg8(CL) & 31)) +} +pub unsafe fn instr32_D3_4_reg(r1: i32) { + write_reg32(r1, shl32(read_reg32(r1), read_reg8(CL) & 31)); +} +pub unsafe fn instr32_D3_5_mem(addr: i32) { + safe_read_write32(addr, &|x| shr32(x, read_reg8(CL) & 31)) +} +pub unsafe fn instr32_D3_5_reg(r1: i32) { + write_reg32(r1, shr32(read_reg32(r1), read_reg8(CL) & 31)); +} +pub unsafe fn instr32_D3_6_mem(addr: i32) { + safe_read_write32(addr, &|x| shl32(x, read_reg8(CL) & 31)) +} +pub unsafe fn instr32_D3_6_reg(r1: i32) { + write_reg32(r1, shl32(read_reg32(r1), read_reg8(CL) & 31)); +} +pub unsafe fn instr32_D3_7_mem(addr: i32) { + safe_read_write32(addr, &|x| sar32(x, read_reg8(CL) & 31)) +} +pub unsafe fn instr32_D3_7_reg(r1: i32) { + write_reg32(r1, sar32(read_reg32(r1), read_reg8(CL) & 31)); +} + +#[no_mangle] +pub unsafe fn instr_D4(arg: i32) { bcd_aam(arg); } +#[no_mangle] +pub unsafe fn instr_D5(arg: i32) { bcd_aad(arg); } +#[no_mangle] +pub unsafe fn instr_D6() { + // salc + write_reg8(AL, -(getcf() as i32)); +} +pub unsafe fn instr_D7() { + // xlat + dbg_assert!(!in_jit); + if is_asize_32() { + write_reg8( + AL, + return_on_pagefault!(safe_read8( + return_on_pagefault!(get_seg_prefix(DS)) + read_reg32(EBX) + read_reg8(AL), + )), + ) + } + else { + write_reg8( + AL, + return_on_pagefault!(safe_read8( + return_on_pagefault!(get_seg_prefix(DS)) + + (read_reg16(BX) + read_reg8(AL) & 0xFFFF), + )), + ) + }; +} + +pub unsafe fn instr_D8_0_mem(addr: i32) { fpu_fadd(0, return_on_pagefault!(fpu_load_m32(addr))); } +pub unsafe fn instr_D8_0_reg(r: i32) { fpu_fadd(0, fpu_get_sti(r)); } +pub unsafe fn instr_D8_1_mem(addr: i32) { fpu_fmul(0, return_on_pagefault!(fpu_load_m32(addr))); } +pub unsafe fn instr_D8_1_reg(r: i32) { fpu_fmul(0, fpu_get_sti(r)); } +pub unsafe fn instr_D8_2_mem(addr: i32) { fpu_fcom(return_on_pagefault!(fpu_load_m32(addr))); } +pub unsafe fn instr_D8_2_reg(r: i32) { fpu_fcom(fpu_get_sti(r)); } +pub unsafe fn instr_D8_3_mem(addr: i32) { fpu_fcomp(return_on_pagefault!(fpu_load_m32(addr))); } +pub unsafe fn instr_D8_3_reg(r: i32) { fpu_fcomp(fpu_get_sti(r)); } +pub unsafe fn instr_D8_4_mem(addr: i32) { fpu_fsub(0, return_on_pagefault!(fpu_load_m32(addr))); } +pub unsafe fn instr_D8_4_reg(r: i32) { fpu_fsub(0, fpu_get_sti(r)); } +pub unsafe fn instr_D8_5_mem(addr: i32) { fpu_fsubr(0, return_on_pagefault!(fpu_load_m32(addr))); } +pub unsafe fn instr_D8_5_reg(r: i32) { fpu_fsubr(0, fpu_get_sti(r)); } +pub unsafe fn instr_D8_6_mem(addr: i32) { fpu_fdiv(0, return_on_pagefault!(fpu_load_m32(addr))); } +pub unsafe fn instr_D8_6_reg(r: i32) { fpu_fdiv(0, fpu_get_sti(r)); } +pub unsafe fn instr_D8_7_mem(addr: i32) { fpu_fdivr(0, return_on_pagefault!(fpu_load_m32(addr))); } +pub unsafe fn instr_D8_7_reg(r: i32) { fpu_fdivr(0, fpu_get_sti(r)); } + +pub unsafe fn instr16_D9_0_mem(addr: i32) { fpu_fldm32(addr); } +pub unsafe fn instr16_D9_0_reg(r: i32) { fpu_push(fpu_get_sti(r)); } +pub unsafe fn instr16_D9_1_mem(_addr: i32) { + dbg_log!("d9/1"); + trigger_ud(); +} +pub unsafe fn instr16_D9_1_reg(r: i32) { fpu_fxch(r); } +pub unsafe fn instr16_D9_2_mem(addr: i32) { fpu_fstm32(addr); } +pub unsafe fn instr16_D9_2_reg(r: i32) { + if r != 0 { + trigger_ud(); + }; +} +pub unsafe fn instr16_D9_3_mem(addr: i32) { fpu_fstm32p(addr); } +pub unsafe fn instr16_D9_3_reg(r: i32) { fpu_fstp(r) } +#[no_mangle] +pub unsafe fn instr16_D9_4_mem(addr: i32) { fpu_fldenv16(addr); } +pub unsafe fn instr32_D9_4_mem(addr: i32) { fpu_fldenv32(addr); } +#[no_mangle] +pub unsafe fn instr16_D9_4_reg(r: i32) { + match r { + 0 => fpu_fchs(), + 1 => fpu_fabs(), + 4 => fpu_ftst(), + 5 => fpu_fxam(), + _ => { + dbg_log!("{:x}", r); + trigger_ud(); + }, + }; +} +#[no_mangle] +pub unsafe fn instr16_D9_5_mem(addr: i32) { fpu_fldcw(addr); } +#[no_mangle] +pub unsafe fn instr16_D9_5_reg(r: i32) { + // fld1/fldl2t/fldl2e/fldpi/fldlg2/fldln2/fldz + match r { + 0 => fpu_push(F80::ONE), + 1 => fpu_push(F80::LN_10 / F80::LN_2), + 2 => fpu_push(F80::LOG2_E), + 3 => fpu_push(F80::PI), + 4 => fpu_push(F80::LN_2 / F80::LN_10), + 5 => fpu_push(F80::LN_2), + 6 => fpu_push(F80::ZERO), + 7 => { + dbg_log!("d9/5/7"); + trigger_ud(); + }, + _ => {}, + }; +} +pub unsafe fn instr16_D9_6_mem(addr: i32) { fpu_fstenv16(addr); } +pub unsafe fn instr32_D9_6_mem(addr: i32) { fpu_fstenv32(addr); } +#[no_mangle] +pub unsafe fn instr16_D9_6_reg(r: i32) { + match r { + 0 => fpu_f2xm1(), + 1 => fpu_fyl2x(), + 2 => fpu_fptan(), + 3 => fpu_fpatan(), + 4 => fpu_fxtract(), + 5 => fpu_fprem(true), // fprem1 + 6 => fpu_fdecstp(), + 7 => fpu_fincstp(), + _ => { + dbg_assert!(false); + }, + }; +} +pub unsafe fn instr16_D9_7_mem(addr: i32) { fpu_fstcw(addr); } +#[no_mangle] +pub unsafe fn instr16_D9_7_reg(r: i32) { + match r { + 0 => fpu_fprem(false), + 1 => fpu_fyl2xp1(), + 2 => fpu_fsqrt(), + 3 => fpu_fsincos(), + 4 => fpu_frndint(), + 5 => fpu_fscale(), + 6 => fpu_fsin(), + 7 => fpu_fcos(), + _ => { + dbg_assert!(false); + }, + }; +} + +pub unsafe fn instr32_D9_0_reg(r: i32) { instr16_D9_0_reg(r) } +pub unsafe fn instr32_D9_1_reg(r: i32) { instr16_D9_1_reg(r) } +pub unsafe fn instr32_D9_2_reg(r: i32) { instr16_D9_2_reg(r) } +pub unsafe fn instr32_D9_3_reg(r: i32) { instr16_D9_3_reg(r) } +pub unsafe fn instr32_D9_4_reg(r: i32) { instr16_D9_4_reg(r) } +pub unsafe fn instr32_D9_5_reg(r: i32) { instr16_D9_5_reg(r) } +pub unsafe fn instr32_D9_6_reg(r: i32) { instr16_D9_6_reg(r) } +pub unsafe fn instr32_D9_7_reg(r: i32) { instr16_D9_7_reg(r) } + +pub unsafe fn instr32_D9_0_mem(r: i32) { instr16_D9_0_mem(r) } +pub unsafe fn instr32_D9_1_mem(r: i32) { instr16_D9_1_mem(r) } +pub unsafe fn instr32_D9_2_mem(r: i32) { instr16_D9_2_mem(r) } +pub unsafe fn instr32_D9_3_mem(r: i32) { instr16_D9_3_mem(r) } +pub unsafe fn instr32_D9_5_mem(r: i32) { instr16_D9_5_mem(r) } +pub unsafe fn instr32_D9_7_mem(r: i32) { instr16_D9_7_mem(r) } + +pub unsafe fn instr_DA_0_mem(addr: i32) { fpu_fadd(0, return_on_pagefault!(fpu_load_i32(addr))); } +pub unsafe fn instr_DA_1_mem(addr: i32) { fpu_fmul(0, return_on_pagefault!(fpu_load_i32(addr))); } +pub unsafe fn instr_DA_2_mem(addr: i32) { fpu_fcom(return_on_pagefault!(fpu_load_i32(addr))); } +pub unsafe fn instr_DA_3_mem(addr: i32) { fpu_fcomp(return_on_pagefault!(fpu_load_i32(addr))); } +pub unsafe fn instr_DA_4_mem(addr: i32) { fpu_fsub(0, return_on_pagefault!(fpu_load_i32(addr))); } +pub unsafe fn instr_DA_5_mem(addr: i32) { fpu_fsubr(0, return_on_pagefault!(fpu_load_i32(addr))); } +pub unsafe fn instr_DA_6_mem(addr: i32) { fpu_fdiv(0, return_on_pagefault!(fpu_load_i32(addr))); } +pub unsafe fn instr_DA_7_mem(addr: i32) { fpu_fdivr(0, return_on_pagefault!(fpu_load_i32(addr))); } +#[no_mangle] +pub unsafe fn instr_DA_0_reg(r: i32) { fpu_fcmovcc(test_b(), r); } +#[no_mangle] +pub unsafe fn instr_DA_1_reg(r: i32) { fpu_fcmovcc(test_z(), r); } +#[no_mangle] +pub unsafe fn instr_DA_2_reg(r: i32) { fpu_fcmovcc(test_be(), r); } +#[no_mangle] +pub unsafe fn instr_DA_3_reg(r: i32) { fpu_fcmovcc(test_p(), r); } +pub unsafe fn instr_DA_4_reg(_r: i32) { trigger_ud(); } +pub unsafe fn instr_DA_5_reg(r: i32) { + if r == 1 { + fpu_fucompp(); + } + else { + trigger_ud(); + }; +} +pub unsafe fn instr_DA_6_reg(_r: i32) { trigger_ud(); } +pub unsafe fn instr_DA_7_reg(_r: i32) { trigger_ud(); } + +pub unsafe fn instr_DB_0_mem(addr: i32) { fpu_fildm32(addr); } +#[no_mangle] +pub unsafe fn instr_DB_1_mem(_addr: i32) { + dbg_log!("fisttp"); + fpu_unimpl(); +} +pub unsafe fn instr_DB_2_mem(addr: i32) { fpu_fistm32(addr); } +pub unsafe fn instr_DB_3_mem(addr: i32) { fpu_fistm32p(addr); } +#[no_mangle] +pub unsafe fn instr_DB_4_mem(_addr: i32) { trigger_ud(); } +pub unsafe fn instr_DB_5_mem(addr: i32) { fpu_fldm80(addr); } +pub unsafe fn instr_DB_6_mem(_addr: i32) { trigger_ud(); } +#[no_mangle] +pub unsafe fn instr_DB_7_mem(addr: i32) { fpu_fst80p(addr); } +#[no_mangle] +pub unsafe fn instr_DB_0_reg(r: i32) { fpu_fcmovcc(!test_b(), r); } +#[no_mangle] +pub unsafe fn instr_DB_1_reg(r: i32) { fpu_fcmovcc(!test_z(), r); } +#[no_mangle] +pub unsafe fn instr_DB_2_reg(r: i32) { fpu_fcmovcc(!test_be(), r); } +#[no_mangle] +pub unsafe fn instr_DB_3_reg(r: i32) { fpu_fcmovcc(!test_p(), r); } +#[no_mangle] +pub unsafe fn instr_DB_4_reg(r: i32) { + if r == 3 { + fpu_finit(); + } + else if r == 4 || r == 1 || r == 0 { + // fsetpm, fdisi, fneni; treated as nop + } + else if r == 2 { + fpu_fclex(); + } + else { + trigger_ud(); + }; +} +pub unsafe fn instr_DB_5_reg(r: i32) { fpu_fucomi(r); } +pub unsafe fn instr_DB_6_reg(r: i32) { fpu_fcomi(r); } +#[no_mangle] +pub unsafe fn instr_DB_7_reg(_r: i32) { trigger_ud(); } + +pub unsafe fn instr_DC_0_mem(addr: i32) { fpu_fadd(0, return_on_pagefault!(fpu_load_m64(addr))); } +pub unsafe fn instr_DC_1_mem(addr: i32) { fpu_fmul(0, return_on_pagefault!(fpu_load_m64(addr))); } +pub unsafe fn instr_DC_2_mem(addr: i32) { fpu_fcom(return_on_pagefault!(fpu_load_m64(addr))); } +pub unsafe fn instr_DC_3_mem(addr: i32) { fpu_fcomp(return_on_pagefault!(fpu_load_m64(addr))); } +pub unsafe fn instr_DC_4_mem(addr: i32) { fpu_fsub(0, return_on_pagefault!(fpu_load_m64(addr))); } +pub unsafe fn instr_DC_5_mem(addr: i32) { fpu_fsubr(0, return_on_pagefault!(fpu_load_m64(addr))); } +pub unsafe fn instr_DC_6_mem(addr: i32) { fpu_fdiv(0, return_on_pagefault!(fpu_load_m64(addr))); } +pub unsafe fn instr_DC_7_mem(addr: i32) { fpu_fdivr(0, return_on_pagefault!(fpu_load_m64(addr))); } +pub unsafe fn instr_DC_0_reg(r: i32) { fpu_fadd(r, fpu_get_sti(r)); } +pub unsafe fn instr_DC_1_reg(r: i32) { fpu_fmul(r, fpu_get_sti(r)); } +pub unsafe fn instr_DC_2_reg(r: i32) { fpu_fcom(fpu_get_sti(r)); } +pub unsafe fn instr_DC_3_reg(r: i32) { fpu_fcomp(fpu_get_sti(r)); } +pub unsafe fn instr_DC_4_reg(r: i32) { fpu_fsub(r, fpu_get_sti(r)); } +pub unsafe fn instr_DC_5_reg(r: i32) { fpu_fsubr(r, fpu_get_sti(r)); } +pub unsafe fn instr_DC_6_reg(r: i32) { fpu_fdiv(r, fpu_get_sti(r)); } +pub unsafe fn instr_DC_7_reg(r: i32) { fpu_fdivr(r, fpu_get_sti(r)); } + +pub unsafe fn instr16_DD_0_mem(addr: i32) { fpu_fldm64(addr); } +#[no_mangle] +pub unsafe fn instr16_DD_1_mem(_addr: i32) { + dbg_log!("fisttp"); + fpu_unimpl(); +} +pub unsafe fn instr16_DD_2_mem(addr: i32) { fpu_fstm64(addr); } +pub unsafe fn instr16_DD_3_mem(addr: i32) { fpu_fstm64p(addr); } +#[no_mangle] +pub unsafe fn instr16_DD_4_mem(addr: i32) { fpu_frstor16(addr); } +#[no_mangle] +pub unsafe fn instr32_DD_4_mem(addr: i32) { fpu_frstor32(addr); } +pub unsafe fn instr16_DD_5_mem(_addr: i32) { + dbg_log!("dd/5"); + trigger_ud(); +} +#[no_mangle] +pub unsafe fn instr16_DD_6_mem(addr: i32) { fpu_fsave16(addr); } +#[no_mangle] +pub unsafe fn instr32_DD_6_mem(addr: i32) { fpu_fsave32(addr); } +#[no_mangle] +pub unsafe fn instr16_DD_7_mem(addr: i32) { fpu_fnstsw_mem(addr); } +pub unsafe fn instr16_DD_0_reg(r: i32) { fpu_ffree(r); } +#[no_mangle] +pub unsafe fn instr16_DD_1_reg(r: i32) { fpu_fxch(r) } +pub unsafe fn instr16_DD_2_reg(r: i32) { fpu_fst(r); } +pub unsafe fn instr16_DD_3_reg(r: i32) { fpu_fstp(r); } +#[no_mangle] +pub unsafe fn instr16_DD_4_reg(r: i32) { fpu_fucom(r); } +pub unsafe fn instr16_DD_5_reg(r: i32) { fpu_fucomp(r); } +#[no_mangle] +pub unsafe fn instr16_DD_6_reg(_r: i32) { trigger_ud(); } +#[no_mangle] +pub unsafe fn instr16_DD_7_reg(_r: i32) { trigger_ud(); } + +pub unsafe fn instr32_DD_0_reg(r: i32) { instr16_DD_0_reg(r) } +#[no_mangle] +pub unsafe fn instr32_DD_1_reg(r: i32) { instr16_DD_1_reg(r) } +pub unsafe fn instr32_DD_2_reg(r: i32) { instr16_DD_2_reg(r) } +pub unsafe fn instr32_DD_3_reg(r: i32) { instr16_DD_3_reg(r) } +#[no_mangle] +pub unsafe fn instr32_DD_4_reg(r: i32) { instr16_DD_4_reg(r) } +pub unsafe fn instr32_DD_5_reg(r: i32) { instr16_DD_5_reg(r) } +#[no_mangle] +pub unsafe fn instr32_DD_6_reg(r: i32) { instr16_DD_6_reg(r) } +#[no_mangle] +pub unsafe fn instr32_DD_7_reg(r: i32) { instr16_DD_7_reg(r) } + +pub unsafe fn instr32_DD_0_mem(r: i32) { instr16_DD_0_mem(r) } +#[no_mangle] +pub unsafe fn instr32_DD_1_mem(r: i32) { instr16_DD_1_mem(r) } +pub unsafe fn instr32_DD_2_mem(r: i32) { instr16_DD_2_mem(r) } +pub unsafe fn instr32_DD_3_mem(r: i32) { instr16_DD_3_mem(r) } +pub unsafe fn instr32_DD_5_mem(r: i32) { instr16_DD_5_mem(r) } +#[no_mangle] +pub unsafe fn instr32_DD_7_mem(r: i32) { instr16_DD_7_mem(r) } + +#[no_mangle] +pub unsafe fn instr_DE_0_mem(addr: i32) { fpu_fadd(0, return_on_pagefault!(fpu_load_i16(addr))); } +#[no_mangle] +pub unsafe fn instr_DE_1_mem(addr: i32) { fpu_fmul(0, return_on_pagefault!(fpu_load_i16(addr))); } +#[no_mangle] +pub unsafe fn instr_DE_2_mem(addr: i32) { fpu_fcom(return_on_pagefault!(fpu_load_i16(addr))); } +#[no_mangle] +pub unsafe fn instr_DE_3_mem(addr: i32) { fpu_fcomp(return_on_pagefault!(fpu_load_i16(addr))); } +#[no_mangle] +pub unsafe fn instr_DE_4_mem(addr: i32) { fpu_fsub(0, return_on_pagefault!(fpu_load_i16(addr))); } +#[no_mangle] +pub unsafe fn instr_DE_5_mem(addr: i32) { fpu_fsubr(0, return_on_pagefault!(fpu_load_i16(addr))); } +#[no_mangle] +pub unsafe fn instr_DE_6_mem(addr: i32) { fpu_fdiv(0, return_on_pagefault!(fpu_load_i16(addr))); } +#[no_mangle] +pub unsafe fn instr_DE_7_mem(addr: i32) { fpu_fdivr(0, return_on_pagefault!(fpu_load_i16(addr))); } + +#[no_mangle] +pub unsafe fn instr_DE_0_reg(r: i32) { + fpu_fadd(r, fpu_get_sti(r)); + fpu_pop(); +} +pub unsafe fn instr_DE_1_reg(r: i32) { + fpu_fmul(r, fpu_get_sti(r)); + fpu_pop(); +} +pub unsafe fn instr_DE_2_reg(r: i32) { + fpu_fcom(fpu_get_sti(r)); + fpu_pop(); +} +pub unsafe fn instr_DE_3_reg(r: i32) { + if r == 1 { + fpu_fcomp(fpu_get_sti(r)); + fpu_pop(); } else { - assert(encodings.length === 1); - return gen_instruction_body_after_fixed_g(encodings[0], size); + trigger_ud(); } } +pub unsafe fn instr_DE_4_reg(r: i32) { + fpu_fsub(r, fpu_get_sti(r)); + fpu_pop(); +} +pub unsafe fn instr_DE_5_reg(r: i32) { + fpu_fsubr(r, fpu_get_sti(r)); + fpu_pop(); +} +pub unsafe fn instr_DE_6_reg(r: i32) { + fpu_fdiv(r, fpu_get_sti(r)); + fpu_pop(); +} +pub unsafe fn instr_DE_7_reg(r: i32) { + fpu_fdivr(r, fpu_get_sti(r)); + fpu_pop(); +} -function gen_instruction_body_after_fixed_g(encoding, size) -{ - const instruction_prefix = []; - const instruction_postfix = - (encoding.block_boundary && !encoding.no_block_boundary_in_interpreted) || - (!encoding.custom && encoding.e) ? - ["after_block_boundary();"] : []; +#[no_mangle] +pub unsafe fn instr_DF_0_mem(addr: i32) { fpu_fildm16(addr) } +#[no_mangle] +pub unsafe fn instr_DF_1_mem(_addr: i32) { + dbg_log!("fisttp"); + fpu_unimpl(); +} +pub unsafe fn instr_DF_2_mem(addr: i32) { fpu_fistm16(addr); } +pub unsafe fn instr_DF_3_mem(addr: i32) { fpu_fistm16p(addr); } +pub unsafe fn instr_DF_4_mem(_addr: i32) { + dbg_log!("fbld"); + fpu_unimpl(); +} +pub unsafe fn instr_DF_5_mem(addr: i32) { fpu_fildm64(addr); } +pub unsafe fn instr_DF_6_mem(addr: i32) { fpu_fbstp(addr); } +pub unsafe fn instr_DF_7_mem(addr: i32) { fpu_fistm64p(addr); } + +#[no_mangle] +pub unsafe fn instr_DF_0_reg(r: i32) { + fpu_ffree(r); + fpu_pop(); +} +#[no_mangle] +pub unsafe fn instr_DF_1_reg(r: i32) { fpu_fxch(r) } +pub unsafe fn instr_DF_2_reg(r: i32) { fpu_fstp(r); } +pub unsafe fn instr_DF_3_reg(r: i32) { fpu_fstp(r); } +pub unsafe fn instr_DF_4_reg(r: i32) { + if r == 0 { + fpu_fnstsw_reg(); + } + else { + trigger_ud(); + }; +} +pub unsafe fn instr_DF_5_reg(r: i32) { fpu_fucomip(r); } +pub unsafe fn instr_DF_6_reg(r: i32) { fpu_fcomip(r); } +pub unsafe fn instr_DF_7_reg(_r: i32) { trigger_ud(); } + +pub unsafe fn instr16_E0(imm8s: i32) { loopne16(imm8s); } +pub unsafe fn instr16_E1(imm8s: i32) { loope16(imm8s); } +pub unsafe fn instr16_E2(imm8s: i32) { loop16(imm8s); } +pub unsafe fn instr16_E3(imm8s: i32) { jcxz16(imm8s); } +pub unsafe fn instr32_E0(imm8s: i32) { loopne32(imm8s); } +pub unsafe fn instr32_E1(imm8s: i32) { loope32(imm8s); } +pub unsafe fn instr32_E2(imm8s: i32) { loop32(imm8s); } +pub unsafe fn instr32_E3(imm8s: i32) { jcxz32(imm8s); } + +#[no_mangle] +pub unsafe fn instr_E4(port: i32) { + if test_privileges_for_io(port, 1) { + write_reg8(AL, io_port_read8(port)); + } +} +#[no_mangle] +pub unsafe fn instr16_E5(port: i32) { + if test_privileges_for_io(port, 2) { + write_reg16(AX, io_port_read16(port)); + } +} +#[no_mangle] +pub unsafe fn instr32_E5(port: i32) { + if test_privileges_for_io(port, 4) { + write_reg32(EAX, io_port_read32(port)); + } +} +#[no_mangle] +pub unsafe fn instr_E6(port: i32) { + if test_privileges_for_io(port, 1) { + io_port_write8(port, read_reg8(AL)); + } +} +#[no_mangle] +pub unsafe fn instr16_E7(port: i32) { + if test_privileges_for_io(port, 2) { + io_port_write16(port, read_reg16(AX)); + } +} +#[no_mangle] +pub unsafe fn instr32_E7(port: i32) { + if test_privileges_for_io(port, 4) { + io_port_write32(port, read_reg32(EAX)); + } +} - if(encoding.task_switch_test || encoding.sse) - { - instruction_prefix.push( - { - type: "if-else", - if_blocks: [ - { - condition: encoding.sse ? "!task_switch_test_mmx()" : "!task_switch_test()", - body: ["return;"], - } - ], - }); - } - - const imm_read = gen_read_imm_call(encoding, size); - const instruction_name = make_instruction_name(encoding, size); - - if(encoding.e) - { - // instruction with modrm byte +pub unsafe fn instr16_E8(imm16: i32) { + // call + return_on_pagefault!(push16(get_real_eip())); + jmp_rel16(imm16); +} +pub unsafe fn instr32_E8(imm32s: i32) { + // call + return_on_pagefault!(push32(get_real_eip())); + *instruction_pointer = *instruction_pointer + imm32s; + dbg_assert!(*is_32 || get_real_eip() < 0x10000); +} +pub unsafe fn instr16_E9(imm16: i32) { + // jmp + jmp_rel16(imm16); +} +pub unsafe fn instr32_E9(imm32s: i32) { + // jmp + *instruction_pointer = *instruction_pointer + imm32s; + dbg_assert!(*is_32 || get_real_eip() < 0x10000); +} - const imm_read = gen_read_imm_call(encoding, size); +#[no_mangle] +pub unsafe fn instr16_EA(new_ip: i32, cs: i32) { + // jmpf + far_jump(new_ip, cs, false, false); + dbg_assert!(*is_32 || get_real_eip() < 0x10000); +} +#[no_mangle] +pub unsafe fn instr32_EA(new_ip: i32, cs: i32) { + // jmpf + far_jump(new_ip, cs, false, true); + dbg_assert!(*is_32 || get_real_eip() < 0x10000); +} - if(encoding.ignore_mod) - { - assert(!imm_read, "Unexpected instruction (ignore mod with immediate value)"); +pub unsafe fn instr16_EB(imm8: i32) { + // jmp near + jmp_rel16(imm8); + dbg_assert!(*is_32 || get_real_eip() < 0x10000); +} +pub unsafe fn instr32_EB(imm8: i32) { + // jmp near + *instruction_pointer = *instruction_pointer + imm8; + dbg_assert!(*is_32 || get_real_eip() < 0x10000); +} - // Has modrm byte, but the 2 mod bits are ignored and both - // operands are always registers (0f20-0f24) +#[no_mangle] +pub unsafe fn instr_EC() { + let port = read_reg16(DX); + if test_privileges_for_io(port, 1) { + write_reg8(AL, io_port_read8(port)); + } +} +#[no_mangle] +pub unsafe fn instr16_ED() { + let port = read_reg16(DX); + if test_privileges_for_io(port, 2) { + write_reg16(AX, io_port_read16(port)); + } +} +#[no_mangle] +pub unsafe fn instr32_ED() { + let port = read_reg16(DX); + if test_privileges_for_io(port, 4) { + write_reg32(EAX, io_port_read32(port)); + } +} +#[no_mangle] +pub unsafe fn instr_EE() { + let port = read_reg16(DX); + if test_privileges_for_io(port, 1) { + io_port_write8(port, read_reg8(AL)); + } +} +#[no_mangle] +pub unsafe fn instr16_EF() { + let port = read_reg16(DX); + if test_privileges_for_io(port, 2) { + io_port_write16(port, read_reg16(AX)); + } +} +#[no_mangle] +pub unsafe fn instr32_EF() { + let port = read_reg16(DX); + if test_privileges_for_io(port, 4) { + io_port_write32(port, read_reg32(EAX)); + } +} - return [].concat( - instruction_prefix, - gen_call(instruction_name, ["modrm_byte & 7", "modrm_byte >> 3 & 7"]), - instruction_postfix - ); - } - else - { - let mem_args; - - if(encoding.custom_modrm_resolve) - { - // requires special handling around modrm_resolve - mem_args = ["modrm_byte"]; - } - else - { - mem_args = ["match modrm_resolve(modrm_byte) { Ok(a) => a, Err(()) => return }"]; - } - - const reg_args = ["modrm_byte & 7"]; - - if(encoding.fixed_g === undefined) - { - mem_args.push("modrm_byte >> 3 & 7"); - reg_args.push("modrm_byte >> 3 & 7"); - } - - if(imm_read) - { - mem_args.push(imm_read); - reg_args.push(imm_read); - } - - return [].concat( - instruction_prefix, - { - type: "if-else", - if_blocks: [ - { - condition: "modrm_byte < 0xC0", - body: [].concat( - gen_call(`${instruction_name}_mem`, mem_args) - ), - } - ], - else_block: { - body: [gen_call(`${instruction_name}_reg`, reg_args)], - }, - }, - instruction_postfix - ); - } +pub unsafe fn instr_F0() { + // lock + if false { + dbg_log!("lock"); } - else - { - const args = []; + // TODO + // This triggers UD when used with + // some instructions that don't write to memory + run_prefix_instruction(); +} - if(imm_read) - { - args.push(imm_read); - } +#[no_mangle] +pub unsafe fn instr_F1() { + // INT1 + // https://code.google.com/p/corkami/wiki/x86oddities#IceBP + dbg_assert!(false); +} - if(encoding.extra_imm16) - { - assert(imm_read); - args.push(wrap_imm_call("read_imm16()")); - } - else if(encoding.extra_imm8) - { - assert(imm_read); - args.push(wrap_imm_call("read_imm8()")); - } +pub unsafe fn instr_F2() { + // repnz + dbg_assert!(*prefixes & prefix::PREFIX_MASK_REP == 0); + *prefixes |= prefix::PREFIX_REPNZ; + run_prefix_instruction(); + *prefixes = 0; +} +pub unsafe fn instr_F3() { + // repz + dbg_assert!(*prefixes & prefix::PREFIX_MASK_REP == 0); + *prefixes |= prefix::PREFIX_REPZ; + run_prefix_instruction(); + *prefixes = 0; +} - return [].concat( - instruction_prefix, - gen_call(instruction_name, args), - instruction_postfix - ); +#[no_mangle] +pub unsafe fn instr_F4() { + if 0 != *cpl { + dbg_log!("#gp hlt with cpl != 0"); + trigger_gp(0); + return; } + + hlt_op(); +} +#[no_mangle] +pub unsafe fn instr_F5() { + // cmc + *flags = (*flags | 1) ^ getcf() as i32; + *flags_changed &= !1; } -function gen_table() -{ - let by_opcode = Object.create(null); - let by_opcode0f = Object.create(null); +pub unsafe fn instr_F6_0_mem(addr: i32, imm: i32) { + test8(return_on_pagefault!(safe_read8(addr)), imm); +} +pub unsafe fn instr_F6_0_reg(r1: i32, imm: i32) { test8(read_reg8(r1), imm); } +pub unsafe fn instr_F6_1_mem(addr: i32, imm: i32) { + test8(return_on_pagefault!(safe_read8(addr)), imm); +} +pub unsafe fn instr_F6_1_reg(r1: i32, imm: i32) { test8(read_reg8(r1), imm); } + +#[no_mangle] +pub unsafe fn instr_F6_2_mem(addr: i32) { safe_read_write8(addr, &|x| !x & 0xFF) } +#[no_mangle] +pub unsafe fn instr_F6_2_reg(r1: i32) { write_reg8(r1, !read_reg8(r1)); } +#[no_mangle] +pub unsafe fn instr_F6_3_mem(addr: i32) { safe_read_write8(addr, &|x| neg8(x)) } +#[no_mangle] +pub unsafe fn instr_F6_3_reg(r1: i32) { write_reg8(r1, neg8(read_reg8(r1))); } +#[no_mangle] +pub unsafe fn instr_F6_4_mem(addr: i32) { mul8(return_on_pagefault!(safe_read8(addr))); } +#[no_mangle] +pub unsafe fn instr_F6_4_reg(r1: i32) { mul8(read_reg8(r1)); } +#[no_mangle] +pub unsafe fn instr_F6_5_mem(addr: i32) { + imul8(return_on_pagefault!(safe_read8(addr)) << 24 >> 24); +} +#[no_mangle] +pub unsafe fn instr_F6_5_reg(r1: i32) { imul8(read_reg8(r1) << 24 >> 24); } +#[no_mangle] +pub unsafe fn instr_F6_6_mem(addr: i32) { div8(return_on_pagefault!(safe_read8(addr)) as u32); } +#[no_mangle] +pub unsafe fn instr_F6_6_reg(r1: i32) { div8(read_reg8(r1) as u32); } +#[no_mangle] +pub unsafe fn instr_F6_7_mem(addr: i32) { + idiv8(return_on_pagefault!(safe_read8(addr)) << 24 >> 24); +} +#[no_mangle] +pub unsafe fn instr_F6_7_reg(r1: i32) { idiv8(read_reg8(r1) << 24 >> 24); } - for(let o of x86_table) - { - let opcode = o.opcode; +pub unsafe fn instr16_F7_0_mem(addr: i32, imm: i32) { + test16(return_on_pagefault!(safe_read16(addr)), imm); +} +pub unsafe fn instr16_F7_0_reg(r1: i32, imm: i32) { test16(read_reg16(r1), imm); } +pub unsafe fn instr16_F7_1_mem(addr: i32, imm: i32) { + test16(return_on_pagefault!(safe_read16(addr)), imm); +} +pub unsafe fn instr16_F7_1_reg(r1: i32, imm: i32) { test16(read_reg16(r1), imm); } +pub unsafe fn instr16_F7_2_mem(addr: i32) { safe_read_write16(addr, &|x| !x & 0xFFFF) } +pub unsafe fn instr16_F7_2_reg(r1: i32) { write_reg16(r1, !read_reg16(r1)); } +pub unsafe fn instr16_F7_3_mem(addr: i32) { safe_read_write16(addr, &|x| neg16(x)) } +pub unsafe fn instr16_F7_3_reg(r1: i32) { write_reg16(r1, neg16(read_reg16(r1))); } +pub unsafe fn instr16_F7_4_mem(addr: i32) { mul16(return_on_pagefault!(safe_read16(addr)) as u32); } +pub unsafe fn instr16_F7_4_reg(r1: i32) { mul16(read_reg16(r1) as u32); } +pub unsafe fn instr16_F7_5_mem(addr: i32) { + imul16(return_on_pagefault!(safe_read16(addr)) << 16 >> 16); +} +pub unsafe fn instr16_F7_5_reg(r1: i32) { imul16(read_reg16(r1) << 16 >> 16); } +pub unsafe fn instr16_F7_6_mem(addr: i32) { div16(return_on_pagefault!(safe_read16(addr)) as u32); } +pub unsafe fn instr16_F7_6_reg(r1: i32) { div16(read_reg16(r1) as u32); } +pub unsafe fn instr16_F7_7_mem(addr: i32) { + idiv16(return_on_pagefault!(safe_read16(addr)) << 16 >> 16); +} +pub unsafe fn instr16_F7_7_reg(r1: i32) { idiv16(read_reg16(r1) << 16 >> 16); } - if((opcode & 0xFF00) === 0x0F00) - { - opcode &= 0xFF; - by_opcode0f[opcode] = by_opcode0f[opcode] || []; - by_opcode0f[opcode].push(o); +pub unsafe fn instr32_F7_0_mem(addr: i32, imm: i32) { + test32(return_on_pagefault!(safe_read32s(addr)), imm); +} +pub unsafe fn instr32_F7_0_reg(r1: i32, imm: i32) { test32(read_reg32(r1), imm); } +pub unsafe fn instr32_F7_1_mem(addr: i32, imm: i32) { + test32(return_on_pagefault!(safe_read32s(addr)), imm); +} +pub unsafe fn instr32_F7_1_reg(r1: i32, imm: i32) { test32(read_reg32(r1), imm); } +pub unsafe fn instr32_F7_2_mem(addr: i32) { safe_read_write32(addr, &|x| !x) } +pub unsafe fn instr32_F7_2_reg(r1: i32) { write_reg32(r1, !read_reg32(r1)); } +pub unsafe fn instr32_F7_3_mem(addr: i32) { safe_read_write32(addr, &|x| neg32(x)) } +pub unsafe fn instr32_F7_3_reg(r1: i32) { write_reg32(r1, neg32(read_reg32(r1))); } +pub unsafe fn instr32_F7_4_mem(addr: i32) { mul32(return_on_pagefault!(safe_read32s(addr))); } +pub unsafe fn instr32_F7_4_reg(r1: i32) { mul32(read_reg32(r1)); } +pub unsafe fn instr32_F7_5_mem(addr: i32) { imul32(return_on_pagefault!(safe_read32s(addr))); } +pub unsafe fn instr32_F7_5_reg(r1: i32) { imul32(read_reg32(r1)); } +pub unsafe fn instr32_F7_6_mem(addr: i32) { + div32(return_on_pagefault!(safe_read32s(addr)) as u32); +} +pub unsafe fn instr32_F7_6_reg(r1: i32) { div32(read_reg32(r1) as u32); } +pub unsafe fn instr32_F7_7_mem(addr: i32) { idiv32(return_on_pagefault!(safe_read32s(addr))); } +pub unsafe fn instr32_F7_7_reg(r1: i32) { idiv32(read_reg32(r1)); } + +pub unsafe fn instr_F8() { + // clc + *flags &= !FLAG_CARRY; + *flags_changed &= !1; +} +pub unsafe fn instr_F9() { + // stc + *flags |= FLAG_CARRY; + *flags_changed &= !1; +} +#[no_mangle] +pub unsafe fn instr_FA_without_fault() -> bool { + // cli + if !*protected_mode + || if 0 != *flags & FLAG_VM { getiopl() == 3 } else { getiopl() >= *cpl as i32 } + { + *flags &= !FLAG_INTERRUPT; + return true; + } + else if false + && getiopl() < 3 + && if 0 != *flags & FLAG_VM { + 0 != *cr.offset(4) & CR4_VME } - else - { - opcode &= 0xFF; - by_opcode[opcode] = by_opcode[opcode] || []; - by_opcode[opcode].push(o); + else { + *cpl == 3 && 0 != *cr.offset(4) & CR4_PVI } + { + *flags &= !FLAG_VIF; + return true; } + else { + dbg_log!("cli #gp"); + return false; + }; +} +pub unsafe fn instr_FA() { + if !instr_FA_without_fault() { + trigger_gp(0); + } +} - let cases = []; - for(let opcode = 0; opcode < 0x100; opcode++) +#[no_mangle] +pub unsafe fn instr_FB_without_fault() -> bool { + // sti + if !*protected_mode + || if 0 != *flags & FLAG_VM { getiopl() == 3 } else { getiopl() >= *cpl as i32 } { - let encoding = by_opcode[opcode]; - assert(encoding && encoding.length); - - let opcode_hex = hex(opcode, 2); - let opcode_high_hex = hex(opcode | 0x100, 2); - - if(encoding[0].os) - { - cases.push({ - conditions: [`0x${opcode_hex}`], - body: gen_instruction_body(encoding, 16), - }); - cases.push({ - conditions: [`0x${opcode_high_hex}`], - body: gen_instruction_body(encoding, 32), - }); + *flags |= FLAG_INTERRUPT; + return true; + } + else if false + && getiopl() < 3 + && *flags & FLAG_VIP == 0 + && if 0 != *flags & FLAG_VM { + 0 != *cr.offset(4) & CR4_VME } - else - { - cases.push({ - conditions: [`0x${opcode_hex}`, `0x${opcode_high_hex}`], - body: gen_instruction_body(encoding, undefined), - }); + else { + *cpl == 3 && 0 != *cr.offset(4) & CR4_PVI } + { + *flags |= FLAG_VIF; + return true; } - const table = { - type: "switch", - condition: "opcode", - cases, - default_case: { - body: ["assert!(false);"] - }, + else { + dbg_log!("sti #gp"); + return false; }; - if(to_generate.interpreter) - { - const code = [ - "#![cfg_attr(rustfmt, rustfmt_skip)]", +} +pub unsafe fn instr_FB() { + if !instr_FB_without_fault() { + trigger_gp(0); + } + else { + *prefixes = 0; + *previous_ip = *instruction_pointer; + *instruction_counter += 1; + run_instruction(return_on_pagefault!(read_imm8()) | (is_osize_32() as i32) << 8); + + handle_irqs(); + } +} - "use cpu::cpu::{after_block_boundary, modrm_resolve};", - "use cpu::cpu::{read_imm8, read_imm8s, read_imm16, read_imm32s, read_moffs};", - "use cpu::cpu::{task_switch_test, trigger_ud, DEBUG};", - "use cpu::instructions;", - "use cpu::global_pointers::{instruction_pointer, prefixes};", +pub unsafe fn instr_FC() { + // cld + *flags &= !FLAG_DIRECTION; +} +pub unsafe fn instr_FD() { + // std + *flags |= FLAG_DIRECTION; +} - "pub unsafe fn run(opcode: u32) {", - table, - "}", - ]; +pub unsafe fn instr_FE_0_mem(addr: i32) { safe_read_write8(addr, &|x| inc8(x)) } +pub unsafe fn instr_FE_0_reg(r1: i32) { write_reg8(r1, inc8(read_reg8(r1))); } +pub unsafe fn instr_FE_1_mem(addr: i32) { safe_read_write8(addr, &|x| dec8(x)) } +pub unsafe fn instr_FE_1_reg(r1: i32) { write_reg8(r1, dec8(read_reg8(r1))); } +pub unsafe fn instr16_FF_0_mem(addr: i32) { safe_read_write16(addr, &|x| inc16(x)) } +pub unsafe fn instr16_FF_0_reg(r1: i32) { write_reg16(r1, inc16(read_reg16(r1))); } +pub unsafe fn instr16_FF_1_mem(addr: i32) { safe_read_write16(addr, &|x| dec16(x)) } +pub unsafe fn instr16_FF_1_reg(r1: i32) { write_reg16(r1, dec16(read_reg16(r1))); } +pub unsafe fn instr16_FF_2_helper(data: i32) { + // call near + let cs = get_seg_cs(); + return_on_pagefault!(push16(get_real_eip())); + *instruction_pointer = cs + data; + dbg_assert!(*is_32 || get_real_eip() < 0x10000); +} +pub unsafe fn instr16_FF_2_mem(addr: i32) { + instr16_FF_2_helper(return_on_pagefault!(safe_read16(addr))); +} +pub unsafe fn instr16_FF_2_reg(r1: i32) { instr16_FF_2_helper(read_reg16(r1)); } - finalize_table_rust( - OUT_DIR, - "interpreter.rs", - rust_ast.print_syntax_tree([].concat(code)).join("\n") + "\n" - ); - } +#[no_mangle] +pub unsafe fn instr16_FF_3_reg(_r: i32) { + dbg_log!("callf #ud"); + trigger_ud(); +} +#[no_mangle] +pub unsafe fn instr16_FF_3_mem(addr: i32) { + // callf + let new_ip = return_on_pagefault!(safe_read16(addr)); + let new_cs = return_on_pagefault!(safe_read16(addr + 2)); + far_jump(new_ip, new_cs, true, false); + dbg_assert!(*is_32 || get_real_eip() < 0x10000); +} +pub unsafe fn instr16_FF_4_helper(data: i32) { + // jmp near + *instruction_pointer = get_seg_cs() + data; + dbg_assert!(*is_32 || get_real_eip() < 0x10000); +} +pub unsafe fn instr16_FF_4_mem(addr: i32) { + instr16_FF_4_helper(return_on_pagefault!(safe_read16(addr))); +} +pub unsafe fn instr16_FF_4_reg(r1: i32) { instr16_FF_4_helper(read_reg16(r1)); } - const cases0f = []; - for(let opcode = 0; opcode < 0x100; opcode++) - { - let encoding = by_opcode0f[opcode]; - - assert(encoding && encoding.length); - - let opcode_hex = hex(opcode, 2); - let opcode_high_hex = hex(opcode | 0x100, 2); - - if(encoding[0].os) - { - cases0f.push({ - conditions: [`0x${opcode_hex}`], - body: gen_instruction_body(encoding, 16), - }); - cases0f.push({ - conditions: [`0x${opcode_high_hex}`], - body: gen_instruction_body(encoding, 32), - }); - } - else - { - let block = { - conditions: [`0x${opcode_hex}`, `0x${opcode_high_hex}`], - body: gen_instruction_body(encoding, undefined), - }; - cases0f.push(block); +#[no_mangle] +pub unsafe fn instr16_FF_5_reg(_r: i32) { + dbg_log!("jmpf #ud"); + trigger_ud(); +} +#[no_mangle] +pub unsafe fn instr16_FF_5_mem(addr: i32) { + // jmpf + let new_ip = return_on_pagefault!(safe_read16(addr)); + let new_cs = return_on_pagefault!(safe_read16(addr + 2)); + far_jump(new_ip, new_cs, false, false); + dbg_assert!(*is_32 || get_real_eip() < 0x10000); +} +pub unsafe fn instr16_FF_6_mem(addr: i32) { + return_on_pagefault!(push16(return_on_pagefault!(safe_read16(addr)))); +} +pub unsafe fn instr16_FF_6_reg(r1: i32) { + return_on_pagefault!(push16(read_reg16(r1))); +} + +pub unsafe fn instr32_FF_0_mem(addr: i32) { safe_read_write32(addr, &|x| inc32(x)) } +pub unsafe fn instr32_FF_0_reg(r1: i32) { write_reg32(r1, inc32(read_reg32(r1))); } +pub unsafe fn instr32_FF_1_mem(addr: i32) { safe_read_write32(addr, &|x| dec32(x)) } +pub unsafe fn instr32_FF_1_reg(r1: i32) { write_reg32(r1, dec32(read_reg32(r1))); } + +pub unsafe fn instr32_FF_2_helper(data: i32) { + // call near + let cs = get_seg_cs(); + return_on_pagefault!(push32(get_real_eip())); + dbg_assert!(*is_32 || data < 0x10000); + *instruction_pointer = cs + data; +} +pub unsafe fn instr32_FF_2_mem(addr: i32) { + instr32_FF_2_helper(return_on_pagefault!(safe_read32s(addr))); +} +pub unsafe fn instr32_FF_2_reg(r1: i32) { instr32_FF_2_helper(read_reg32(r1)); } +#[no_mangle] +pub unsafe fn instr32_FF_3_reg(_r: i32) { + dbg_log!("callf #ud"); + trigger_ud(); +} +#[no_mangle] +pub unsafe fn instr32_FF_3_mem(addr: i32) { + // callf + let new_ip = return_on_pagefault!(safe_read32s(addr)); + let new_cs = return_on_pagefault!(safe_read16(addr + 4)); + if !*protected_mode || vm86_mode() { + if 0 != new_ip as u32 & 0xFFFF0000 { + dbg_assert!(false); } } + far_jump(new_ip, new_cs, true, true); + dbg_assert!(*is_32 || new_ip < 0x10000); +} - const table0f = { - type: "switch", - condition: "opcode", - cases: cases0f, - default_case: { - body: ["assert!(false);"] - }, - }; +pub unsafe fn instr32_FF_4_helper(data: i32) { + // jmp near + dbg_assert!(*is_32 || data < 0x10000); + *instruction_pointer = get_seg_cs() + data; +} +pub unsafe fn instr32_FF_4_mem(addr: i32) { + instr32_FF_4_helper(return_on_pagefault!(safe_read32s(addr))); +} +pub unsafe fn instr32_FF_4_reg(r1: i32) { instr32_FF_4_helper(read_reg32(r1)); } - if(to_generate.interpreter0f) - { - const code = [ - "#![cfg_attr(rustfmt, rustfmt_skip)]", - - "use cpu::cpu::{after_block_boundary, modrm_resolve};", - "use cpu::cpu::{read_imm8, read_imm16, read_imm32s};", - "use cpu::cpu::{task_switch_test, task_switch_test_mmx, trigger_ud};", - "use cpu::cpu::DEBUG;", - "use cpu::instructions_0f;", - "use cpu::global_pointers::{instruction_pointer, prefixes};", - - "pub unsafe fn run(opcode: u32) {", - table0f, - "}", - ]; - - finalize_table_rust( - OUT_DIR, - "interpreter0f.rs", - rust_ast.print_syntax_tree([].concat(code)).join("\n") + "\n" - ); +#[no_mangle] +pub unsafe fn instr32_FF_5_reg(_r: i32) { + dbg_log!("jmpf #ud"); + trigger_ud(); +} +#[no_mangle] +pub unsafe fn instr32_FF_5_mem(addr: i32) { + // jmpf + let new_ip = return_on_pagefault!(safe_read32s(addr)); + let new_cs = return_on_pagefault!(safe_read16(addr + 4)); + if !*protected_mode || vm86_mode() { + if 0 != new_ip as u32 & 0xFFFF0000 { + dbg_assert!(false); + } } + far_jump(new_ip, new_cs, false, true); + dbg_assert!(*is_32 || new_ip < 0x10000); +} +pub unsafe fn instr32_FF_6_mem(addr: i32) { + return_on_pagefault!(push32(return_on_pagefault!(safe_read32s(addr)))); +} +pub unsafe fn instr32_FF_6_reg(r1: i32) { + return_on_pagefault!(push32(read_reg32(r1))); } From ff42c6eeaccf91d92a45908f7a9629a71fbb1791 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 5 Sep 2023 17:58:28 +0200 Subject: [PATCH 040/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 37 +++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index f7e0ba1bad..e5e01bbd08 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1639,7 +1639,42 @@ pub unsafe fn instr32_D3_7_mem(addr: i32) { pub unsafe fn instr32_D3_7_reg(r1: i32) { write_reg32(r1, sar32(read_reg32(r1), read_reg8(CL) & 31)); } - +#[no_mangle] +pub unsafe fn instr_DF(source: reg128, r: i32) { + // haddps xmm, xmm/mem128 + let destination = read_xmm128s(r); + let result = reg128 { + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], + ], + }; + write_xmm_reg128(r, result); +} +pub unsafe fn instr_DF_reg(r1: i32, r2: i32) { instr_DF(read_xmm128s(r1), r2); } +pub unsafe fn instr_DF_mem(addr: i32, r: i32) { + instr_DF(return_on_pagefault!(safe_read128s(addr)), r); +} +#[no_mangle] +pub unsafe fn instr_DD(source: reg128, r: i32) { + // haddps xmm, xmm/mem128 + let destination = read_xmm128s(r); + let result = reg128 { + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], + ], + }; + write_xmm_reg128(r, result); +} +pub unsafe fn instr_DD_reg(r1: i32, r2: i32) { instr_DD(read_xmm128s(r1), r2); } +pub unsafe fn instr_DD_mem(addr: i32, r: i32) { + instr_DD(return_on_pagefault!(safe_read128s(addr)), r); +} #[no_mangle] pub unsafe fn instr_D4(arg: i32) { bcd_aam(arg); } #[no_mangle] From 639d9dffb48a345da8c2ccad3a4da1f803d8eb00 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 5 Sep 2023 19:27:37 +0200 Subject: [PATCH 041/180] Update instructions.rs From c74b7f37088d55abd2bf2c40e2ce14b96998693e Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 5 Sep 2023 19:46:07 +0200 Subject: [PATCH 042/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 36 --------------------------------- 1 file changed, 36 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 59d92dde04..e3f08def1c 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1916,42 +1916,6 @@ pub unsafe fn instr_F20F7C_mem(addr: i32, r: i32) { instr_F20F7C(return_on_pagefault!(safe_read128s(addr)), r); } #[no_mangle] -pub unsafe fn instr_DF(source: reg128, r: i32) { - // fisttp xmm, xmm/mem128 - let destination = read_xmm128s(r); - let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], - ], - }; - write_xmm_reg128(r, result); -} -pub unsafe fn instr_DF_reg(r1: i32, r2: i32) { instr_DF(read_xmm128s(r1), r2); } -pub unsafe fn instr_DF_mem(addr: i32, r: i32) { - instr_DF(return_on_pagefault!(safe_read128s(addr)), r); -} -#[no_mangle] -pub unsafe fn instr_DD(source: reg128, r: i32) { - // fisttp xmm, xmm/mem128 - let destination = read_xmm128s(r); - let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], - ], - }; - write_xmm_reg128(r, result); -} -pub unsafe fn instr_DD_reg(r1: i32, r2: i32) { instr_DD(read_xmm128s(r1), r2); } -pub unsafe fn instr_DD_mem(addr: i32, r: i32) { - instr_DD(return_on_pagefault!(safe_read128s(addr)), r); -} -#[no_mangle] pub unsafe fn instr_F20F7D(source: reg128, r: i32) { // hsubps xmm, xmm/mem128 let destination = read_xmm128s(r); From 9822ed3b31fb2935ac98fbb006b8f587948b0c63 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 6 Sep 2023 14:12:36 +0200 Subject: [PATCH 043/180] Update jit_instructions.rs --- src/rust/jit_instructions.rs | 39 ++---------------------------------- 1 file changed, 2 insertions(+), 37 deletions(-) diff --git a/src/rust/jit_instructions.rs b/src/rust/jit_instructions.rs index ca8cfc9a7c..2ce637f67f 100644 --- a/src/rust/jit_instructions.rs +++ b/src/rust/jit_instructions.rs @@ -3852,17 +3852,7 @@ pub fn instr32_DD_0_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_0_reg_jit pub fn instr32_DD_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { instr16_DD_0_mem_jit(ctx, modrm_byte) } -pub fn instr16_DD_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { - codegen::gen_fpu_load_m64(ctx, modrm_byte); - ctx.builder.call_fn2_i64_i32("fpu_push"); -} -pub fn instr16_DD_1_reg_jit(ctx: &mut JitContext, r: u32) { - codegen::gen_fn1_const(ctx.builder, "fpu_ffree", r); -} -pub fn instr32_DD_1_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_1_reg_jit(ctx, r) } -pub fn instr32_DD_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { - instr16_DD_1_mem_jit(ctx, modrm_byte) -} + pub fn instr16_DD_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { codegen::gen_modrm_resolve(ctx, modrm_byte); let address_local = ctx.builder.set_new_local(); @@ -3984,32 +3974,7 @@ pub fn instr_DE_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { pub fn instr_DE_7_reg_jit(ctx: &mut JitContext, r: u32) { instr_group_DE_reg_jit(ctx, r, "fpu_fdivr") } -pub fn instr_DF_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { - codegen::gen_modrm_resolve(ctx, modrm_byte); - let address_local = ctx.builder.set_new_local(); - codegen::gen_fpu_get_sti(ctx, 0); - ctx.builder.call_fn2_i64_i32_ret("fpu_convert_to_i16"); - let value_local = ctx.builder.set_new_local(); - codegen::gen_safe_write16(ctx, &address_local, &value_local); - ctx.builder.free_local(address_local); - ctx.builder.free_local(value_local); -} -pub fn instr_DF_0_reg_jit(ctx: &mut JitContext, r: u32) { - codegen::gen_fn1_const(ctx.builder, "fpu_fstp", r); -} -pub fn instr_DF_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { - codegen::gen_modrm_resolve(ctx, modrm_byte); - let address_local = ctx.builder.set_new_local(); - codegen::gen_fpu_get_sti(ctx, 0); - ctx.builder.call_fn2_i64_i32_ret("fpu_convert_to_i16"); - let value_local = ctx.builder.set_new_local(); - codegen::gen_safe_write16(ctx, &address_local, &value_local); - ctx.builder.free_local(address_local); - ctx.builder.free_local(value_local); -} -pub fn instr_DF_1_reg_jit(ctx: &mut JitContext, r: u32) { - codegen::gen_fn1_const(ctx.builder, "fpu_fstp", r); -} + pub fn instr_DF_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { codegen::gen_modrm_resolve(ctx, modrm_byte); let address_local = ctx.builder.set_new_local(); From 99f069c48f9e6afd17f437cd347f16532375d92a Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 6 Sep 2023 14:47:47 +0200 Subject: [PATCH 044/180] Update jit_instructions.rs --- src/rust/jit_instructions.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/rust/jit_instructions.rs b/src/rust/jit_instructions.rs index 2ce637f67f..cca6b0b2c4 100644 --- a/src/rust/jit_instructions.rs +++ b/src/rust/jit_instructions.rs @@ -6218,18 +6218,6 @@ pub fn instr_660F7C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) pub fn instr_660F7C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_read128_xmm_xmm(ctx, "instr_660F7C", r1, r2); } -pub fn instr_DF_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { - sse_read128_xmm_mem(ctx, "instr_DF", modrm_byte, r); -} -pub fn instr_DF_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { - sse_read128_xmm_xmm(ctx, "instr_DF", r1, r2); -} -pub fn instr_DD_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { - sse_read128_xmm_mem(ctx, "instr_DD", modrm_byte, r); -} -pub fn instr_DD_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { - sse_read128_xmm_xmm(ctx, "instr_DD", r1, r2); -} pub fn instr_F30F5B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { sse_read128_xmm_mem(ctx, "instr_F30F5B", modrm_byte, r); } From b133aa4a16599d144a4baf5cb508a029e68efb38 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 6 Sep 2023 15:10:09 +0200 Subject: [PATCH 045/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index e3f08def1c..a6891a6b4d 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -3238,7 +3238,7 @@ pub unsafe fn instr_0FA2() { // pentium eax = 3 | 6 << 4 | 15 << 8; ebx = 1 << 16 | 8 << 8; // cpu count, clflush size - ecx = 1 << 23 | 1 << 30 | 1 << 0; // popcnt, rdrand, sse3 + ecx = 1 << 0 | 1 << 23 | 1 << 30; // popcnt, rdrand, sse3 let vme = 0 << 1; if ::config::VMWARE_HYPERVISOR_PORT { ecx |= 1 << 31 From a7e9a09ac7c2b77a3f3c2de4b35821e0a85abc34 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 7 Sep 2023 14:44:43 +0200 Subject: [PATCH 046/180] Update fpu.rs --- src/rust/cpu/fpu.rs | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/fpu.rs b/src/rust/cpu/fpu.rs index 23e673f3e2..6da8e0cfcc 100644 --- a/src/rust/cpu/fpu.rs +++ b/src/rust/cpu/fpu.rs @@ -625,7 +625,6 @@ pub unsafe fn fpu_fstp(r: i32) { fpu_fst(r); fpu_pop(); } - #[no_mangle] pub unsafe fn fpu_fbstp(addr: i32) { match writable_or_pagefault(addr, 26) { @@ -654,7 +653,34 @@ pub unsafe fn fpu_fbstp(addr: i32) { } fpu_pop(); } - +#[no_mangle] +pub unsafe fn fpu_fisttp(addr: i32) { + match writable_or_pagefault(addr, 26) { + Ok(()) => *page_fault = false, + Err(()) => { + *page_fault = true; + return; + }, + } + let st0 = fpu_get_st0(); + let mut x = st0.to_i64().unsigned_abs(); + if x <= 99_9999_9999_9999_9999 { + for i in 0..=8 { + let low = x % 10; + x /= 10; + let high = x % 10; + x /= 10; + safe_write8(addr + i, (high as i32) << 4 | low as i32).unwrap(); + } + safe_write8(addr + 9, if st0.sign() { 0x80 } else { 0 }).unwrap(); + } + else { + fpu_invalid_arithmetic(); + safe_write64(addr + 0, 0xC000_0000_0000_0000).unwrap(); + safe_write16(addr + 8, 0xFFFF).unwrap(); + } + fpu_pop(); +} #[no_mangle] pub unsafe fn fpu_fsub(target_index: i32, val: F80) { let st0 = fpu_get_st0(); From 721282a49784f8c95489bd6092c8aeaeb284209f Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 7 Sep 2023 15:24:05 +0200 Subject: [PATCH 047/180] Update x86_table.js --- gen/x86_table.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gen/x86_table.js b/gen/x86_table.js index 63dba944f8..8c7853cb43 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -324,7 +324,7 @@ const encodings = [ { opcode: 0xDC, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDD, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, - { opcode: 0xDD, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, // fisttp (sse3) + { opcode: 0xDD, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, // fisttp (sse3) { opcode: 0xDD, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, { opcode: 0xDD, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, { opcode: 0xDD, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, skip_mem: 1 }, // frstor @@ -342,7 +342,7 @@ const encodings = [ { opcode: 0xDE, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 0, custom: 0, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDF, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, skip_mem: 1 }, // fisttp (sse3) + { opcode: 0xDF, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) { opcode: 0xDF, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDF, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, skip_mem: 1 }, // unimplemented: Binary Coded Decimals From 6dd06e99f152933ccc957f587a3e8d42a6f5caba Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 7 Sep 2023 15:37:38 +0200 Subject: [PATCH 048/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index e5e01bbd08..a2a856cc84 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1915,10 +1915,7 @@ pub unsafe fn instr_DC_7_reg(r: i32) { fpu_fdivr(r, fpu_get_sti(r)); } pub unsafe fn instr16_DD_0_mem(addr: i32) { fpu_fldm64(addr); } #[no_mangle] -pub unsafe fn instr16_DD_1_mem(_addr: i32) { - dbg_log!("fisttp"); - fpu_unimpl(); -} +pub unsafe fn instr16_DD_1_mem(addr: i32) { fpu_fisttp(addr); } pub unsafe fn instr16_DD_2_mem(addr: i32) { fpu_fstm64(addr); } pub unsafe fn instr16_DD_3_mem(addr: i32) { fpu_fstm64p(addr); } #[no_mangle] From ff03f0797475b615ffb670c3dd64f97181f9920f Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 7 Sep 2023 15:40:51 +0200 Subject: [PATCH 049/180] Update jit_instructions.rs --- src/rust/jit_instructions.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/rust/jit_instructions.rs b/src/rust/jit_instructions.rs index cca6b0b2c4..4ac6d28157 100644 --- a/src/rust/jit_instructions.rs +++ b/src/rust/jit_instructions.rs @@ -3852,7 +3852,17 @@ pub fn instr32_DD_0_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_0_reg_jit pub fn instr32_DD_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { instr16_DD_0_mem_jit(ctx, modrm_byte) } - +pub fn instr16_DD_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { + codegen::gen_fpu_load_m64(ctx, modrm_byte); + ctx.builder.call_fn2_i64_i32("fpu_push"); +} +pub fn instr16_DD_1_reg_jit(ctx: &mut JitContext, r: u32) { + codegen::gen_fn1_const(ctx.builder, "fpu_fisttp", r); +} +pub fn instr32_DD_1_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_1_reg_jit(ctx, r) } +pub fn instr32_DD_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { + instr16_DD_1_mem_jit(ctx, modrm_byte) +} pub fn instr16_DD_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { codegen::gen_modrm_resolve(ctx, modrm_byte); let address_local = ctx.builder.set_new_local(); From 8ff8a8aa63b0d09181ffe16de114d5402275f3cd Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 8 Sep 2023 13:48:30 +0200 Subject: [PATCH 050/180] Update fpu.rs --- src/rust/cpu/fpu.rs | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/src/rust/cpu/fpu.rs b/src/rust/cpu/fpu.rs index 6da8e0cfcc..802dc917df 100644 --- a/src/rust/cpu/fpu.rs +++ b/src/rust/cpu/fpu.rs @@ -662,24 +662,15 @@ pub unsafe fn fpu_fisttp(addr: i32) { return; }, } - let st0 = fpu_get_st0(); - let mut x = st0.to_i64().unsigned_abs(); - if x <= 99_9999_9999_9999_9999 { - for i in 0..=8 { - let low = x % 10; - x /= 10; - let high = x % 10; - x /= 10; - safe_write8(addr + i, (high as i32) << 4 | low as i32).unwrap(); - } - safe_write8(addr + 9, if st0.sign() { 0x80 } else { 0 }).unwrap(); - } - else { - fpu_invalid_arithmetic(); - safe_write64(addr + 0, 0xC000_0000_0000_0000).unwrap(); - safe_write16(addr + 8, 0xFFFF).unwrap(); - } - fpu_pop(); + let high_bits = 0xFFFF0000u32 as i32; + safe_write32(addr + 0, high_bits + *fpu_control_word as i32).unwrap(); + safe_write32(addr + 4, high_bits + fpu_load_status_word() as i32).unwrap(); + safe_write32(addr + 8, high_bits + fpu_load_tag_word()).unwrap(); + safe_write32(addr + 12, *fpu_ip).unwrap(); + safe_write16(addr + 16, *fpu_ip_selector).unwrap(); + safe_write16(addr + 18, *fpu_opcode).unwrap(); + safe_write32(addr + 20, *fpu_dp).unwrap(); + safe_write32(addr + 24, high_bits | *fpu_dp_selector).unwrap(); } #[no_mangle] pub unsafe fn fpu_fsub(target_index: i32, val: F80) { From 3d4cd78beca5d874ffb616dcc56f28cf18cd4ed4 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 8 Sep 2023 14:14:28 +0200 Subject: [PATCH 051/180] Update fpu.rs --- src/rust/cpu/fpu.rs | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/src/rust/cpu/fpu.rs b/src/rust/cpu/fpu.rs index 802dc917df..bcca443b9a 100644 --- a/src/rust/cpu/fpu.rs +++ b/src/rust/cpu/fpu.rs @@ -653,25 +653,7 @@ pub unsafe fn fpu_fbstp(addr: i32) { } fpu_pop(); } -#[no_mangle] -pub unsafe fn fpu_fisttp(addr: i32) { - match writable_or_pagefault(addr, 26) { - Ok(()) => *page_fault = false, - Err(()) => { - *page_fault = true; - return; - }, - } - let high_bits = 0xFFFF0000u32 as i32; - safe_write32(addr + 0, high_bits + *fpu_control_word as i32).unwrap(); - safe_write32(addr + 4, high_bits + fpu_load_status_word() as i32).unwrap(); - safe_write32(addr + 8, high_bits + fpu_load_tag_word()).unwrap(); - safe_write32(addr + 12, *fpu_ip).unwrap(); - safe_write16(addr + 16, *fpu_ip_selector).unwrap(); - safe_write16(addr + 18, *fpu_opcode).unwrap(); - safe_write32(addr + 20, *fpu_dp).unwrap(); - safe_write32(addr + 24, high_bits | *fpu_dp_selector).unwrap(); -} + #[no_mangle] pub unsafe fn fpu_fsub(target_index: i32, val: F80) { let st0 = fpu_get_st0(); @@ -682,7 +664,11 @@ pub unsafe fn fpu_fsubr(target_index: i32, val: F80) { let st0 = fpu_get_st0(); fpu_write_st(*fpu_stack_ptr as i32 + target_index & 7, val - st0) } - +#[no_mangle] +pub unsafe fn fpu_fisttp(target_index: i32, val: F80) { + let st0 = fpu_get_st0(); + fpu_write_st(*fpu_stack_ptr as i32 + target_index & 7, val - st0) +} #[no_mangle] pub unsafe fn fpu_ftst() { let x = fpu_get_st0(); From 17445d9371d4f39bf23a0529ad541e4642f6aaa4 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 8 Sep 2023 16:12:02 +0200 Subject: [PATCH 052/180] Update fpu.rs --- src/rust/cpu/fpu.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/rust/cpu/fpu.rs b/src/rust/cpu/fpu.rs index bcca443b9a..8c255a74c5 100644 --- a/src/rust/cpu/fpu.rs +++ b/src/rust/cpu/fpu.rs @@ -243,14 +243,18 @@ pub unsafe fn fpu_fdivr(target_index: i32, val: F80) { } #[no_mangle] pub unsafe fn fpu_ffree(r: i32) { *fpu_stack_empty |= 1 << (*fpu_stack_ptr as i32 + r & 7); } - #[no_mangle] pub unsafe fn fpu_fildm16(addr: i32) { fpu_push(return_on_pagefault!(fpu_load_i16(addr))); } #[no_mangle] pub unsafe fn fpu_fildm32(addr: i32) { fpu_push(return_on_pagefault!(fpu_load_i32(addr))); } #[no_mangle] pub unsafe fn fpu_fildm64(addr: i32) { fpu_push(return_on_pagefault!(fpu_load_i64(addr))); } - +#[no_mangle] +pub unsafe fn fpu_fisttpm16(addr: i32) { fpu_push(return_on_pagefault!(fpu_load_i16(addr))); } +#[no_mangle] +pub unsafe fn fpu_fisttpm32(addr: i32) { fpu_push(return_on_pagefault!(fpu_load_i32(addr))); } +#[no_mangle] +pub unsafe fn fpu_fisttpm64(addr: i32) { fpu_push(return_on_pagefault!(fpu_load_i64(addr))); } #[no_mangle] pub unsafe fn fpu_push(x: F80) { *fpu_stack_ptr = *fpu_stack_ptr - 1 & 7; @@ -665,10 +669,6 @@ pub unsafe fn fpu_fsubr(target_index: i32, val: F80) { fpu_write_st(*fpu_stack_ptr as i32 + target_index & 7, val - st0) } #[no_mangle] -pub unsafe fn fpu_fisttp(target_index: i32, val: F80) { - let st0 = fpu_get_st0(); - fpu_write_st(*fpu_stack_ptr as i32 + target_index & 7, val - st0) -} #[no_mangle] pub unsafe fn fpu_ftst() { let x = fpu_get_st0(); @@ -765,6 +765,7 @@ pub unsafe fn fpu_fxch(i: i32) { fpu_write_st(*fpu_stack_ptr as i32 + i & 7, fpu_get_st0()); fpu_write_st(*fpu_stack_ptr as i32, sti); } + pub unsafe fn fpu_fyl2x() { let st0 = fpu_get_st0(); if st0 < F80::ZERO { From d83b0321115bf6c6e971e0fdca551fec7b3a553d Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 8 Sep 2023 16:23:56 +0200 Subject: [PATCH 053/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index a2a856cc84..dcd7d00650 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -2026,10 +2026,7 @@ pub unsafe fn instr_DE_7_reg(r: i32) { #[no_mangle] pub unsafe fn instr_DF_0_mem(addr: i32) { fpu_fildm16(addr) } #[no_mangle] -pub unsafe fn instr_DF_1_mem(_addr: i32) { - dbg_log!("fisttp"); - fpu_unimpl(); -} +pub unsafe fn instr_DF_1_mem(addr: i32) { fpu_fisttpm16(addr); } pub unsafe fn instr_DF_2_mem(addr: i32) { fpu_fistm16(addr); } pub unsafe fn instr_DF_3_mem(addr: i32) { fpu_fistm16p(addr); } pub unsafe fn instr_DF_4_mem(_addr: i32) { From 6b55c47ca039cfacf6eb92428d0cd877429c39e5 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 8 Sep 2023 16:25:33 +0200 Subject: [PATCH 054/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index dcd7d00650..7c8638b69a 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1915,7 +1915,7 @@ pub unsafe fn instr_DC_7_reg(r: i32) { fpu_fdivr(r, fpu_get_sti(r)); } pub unsafe fn instr16_DD_0_mem(addr: i32) { fpu_fldm64(addr); } #[no_mangle] -pub unsafe fn instr16_DD_1_mem(addr: i32) { fpu_fisttp(addr); } +pub unsafe fn instr16_DD_1_mem(addr: i32) { fpu_fisttpm64(addr); } pub unsafe fn instr16_DD_2_mem(addr: i32) { fpu_fstm64(addr); } pub unsafe fn instr16_DD_3_mem(addr: i32) { fpu_fstm64p(addr); } #[no_mangle] From 9be79e8ed187f10edefed0a922e3e642a5e05a7e Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 8 Sep 2023 16:36:59 +0200 Subject: [PATCH 055/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index 7c8638b69a..509518700b 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1856,10 +1856,7 @@ pub unsafe fn instr_DA_7_reg(_r: i32) { trigger_ud(); } pub unsafe fn instr_DB_0_mem(addr: i32) { fpu_fildm32(addr); } #[no_mangle] -pub unsafe fn instr_DB_1_mem(_addr: i32) { - dbg_log!("fisttp"); - fpu_unimpl(); -} +pub unsafe fn instr_DB_1_mem(addr: i32) { fpu_fisttpm32(addr); } pub unsafe fn instr_DB_2_mem(addr: i32) { fpu_fistm32(addr); } pub unsafe fn instr_DB_3_mem(addr: i32) { fpu_fistm32p(addr); } #[no_mangle] From f55af43c233764294879b1d9ac8157e6ad56bd02 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 8 Sep 2023 19:01:23 +0200 Subject: [PATCH 056/180] Update fpu.rs --- src/rust/cpu/fpu.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/rust/cpu/fpu.rs b/src/rust/cpu/fpu.rs index 8c255a74c5..23e673f3e2 100644 --- a/src/rust/cpu/fpu.rs +++ b/src/rust/cpu/fpu.rs @@ -243,18 +243,14 @@ pub unsafe fn fpu_fdivr(target_index: i32, val: F80) { } #[no_mangle] pub unsafe fn fpu_ffree(r: i32) { *fpu_stack_empty |= 1 << (*fpu_stack_ptr as i32 + r & 7); } + #[no_mangle] pub unsafe fn fpu_fildm16(addr: i32) { fpu_push(return_on_pagefault!(fpu_load_i16(addr))); } #[no_mangle] pub unsafe fn fpu_fildm32(addr: i32) { fpu_push(return_on_pagefault!(fpu_load_i32(addr))); } #[no_mangle] pub unsafe fn fpu_fildm64(addr: i32) { fpu_push(return_on_pagefault!(fpu_load_i64(addr))); } -#[no_mangle] -pub unsafe fn fpu_fisttpm16(addr: i32) { fpu_push(return_on_pagefault!(fpu_load_i16(addr))); } -#[no_mangle] -pub unsafe fn fpu_fisttpm32(addr: i32) { fpu_push(return_on_pagefault!(fpu_load_i32(addr))); } -#[no_mangle] -pub unsafe fn fpu_fisttpm64(addr: i32) { fpu_push(return_on_pagefault!(fpu_load_i64(addr))); } + #[no_mangle] pub unsafe fn fpu_push(x: F80) { *fpu_stack_ptr = *fpu_stack_ptr - 1 & 7; @@ -629,6 +625,7 @@ pub unsafe fn fpu_fstp(r: i32) { fpu_fst(r); fpu_pop(); } + #[no_mangle] pub unsafe fn fpu_fbstp(addr: i32) { match writable_or_pagefault(addr, 26) { @@ -668,7 +665,7 @@ pub unsafe fn fpu_fsubr(target_index: i32, val: F80) { let st0 = fpu_get_st0(); fpu_write_st(*fpu_stack_ptr as i32 + target_index & 7, val - st0) } -#[no_mangle] + #[no_mangle] pub unsafe fn fpu_ftst() { let x = fpu_get_st0(); @@ -765,7 +762,6 @@ pub unsafe fn fpu_fxch(i: i32) { fpu_write_st(*fpu_stack_ptr as i32 + i & 7, fpu_get_st0()); fpu_write_st(*fpu_stack_ptr as i32, sti); } - pub unsafe fn fpu_fyl2x() { let st0 = fpu_get_st0(); if st0 < F80::ZERO { From 026aa7e5eec8cc7cba6f4ac7341bedf2bfbcc1fd Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 8 Sep 2023 19:16:39 +0200 Subject: [PATCH 057/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index 509518700b..a2a856cc84 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1856,7 +1856,10 @@ pub unsafe fn instr_DA_7_reg(_r: i32) { trigger_ud(); } pub unsafe fn instr_DB_0_mem(addr: i32) { fpu_fildm32(addr); } #[no_mangle] -pub unsafe fn instr_DB_1_mem(addr: i32) { fpu_fisttpm32(addr); } +pub unsafe fn instr_DB_1_mem(_addr: i32) { + dbg_log!("fisttp"); + fpu_unimpl(); +} pub unsafe fn instr_DB_2_mem(addr: i32) { fpu_fistm32(addr); } pub unsafe fn instr_DB_3_mem(addr: i32) { fpu_fistm32p(addr); } #[no_mangle] @@ -1912,7 +1915,7 @@ pub unsafe fn instr_DC_7_reg(r: i32) { fpu_fdivr(r, fpu_get_sti(r)); } pub unsafe fn instr16_DD_0_mem(addr: i32) { fpu_fldm64(addr); } #[no_mangle] -pub unsafe fn instr16_DD_1_mem(addr: i32) { fpu_fisttpm64(addr); } +pub unsafe fn instr16_DD_1_mem(addr: i32) { fpu_fisttp(addr); } pub unsafe fn instr16_DD_2_mem(addr: i32) { fpu_fstm64(addr); } pub unsafe fn instr16_DD_3_mem(addr: i32) { fpu_fstm64p(addr); } #[no_mangle] @@ -2023,7 +2026,10 @@ pub unsafe fn instr_DE_7_reg(r: i32) { #[no_mangle] pub unsafe fn instr_DF_0_mem(addr: i32) { fpu_fildm16(addr) } #[no_mangle] -pub unsafe fn instr_DF_1_mem(addr: i32) { fpu_fisttpm16(addr); } +pub unsafe fn instr_DF_1_mem(_addr: i32) { + dbg_log!("fisttp"); + fpu_unimpl(); +} pub unsafe fn instr_DF_2_mem(addr: i32) { fpu_fistm16(addr); } pub unsafe fn instr_DF_3_mem(addr: i32) { fpu_fistm16p(addr); } pub unsafe fn instr_DF_4_mem(_addr: i32) { From b2acd54899a9865fc51d3b020d29a230ad8db5be Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 8 Sep 2023 19:21:28 +0200 Subject: [PATCH 058/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index a2a856cc84..509518700b 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1856,10 +1856,7 @@ pub unsafe fn instr_DA_7_reg(_r: i32) { trigger_ud(); } pub unsafe fn instr_DB_0_mem(addr: i32) { fpu_fildm32(addr); } #[no_mangle] -pub unsafe fn instr_DB_1_mem(_addr: i32) { - dbg_log!("fisttp"); - fpu_unimpl(); -} +pub unsafe fn instr_DB_1_mem(addr: i32) { fpu_fisttpm32(addr); } pub unsafe fn instr_DB_2_mem(addr: i32) { fpu_fistm32(addr); } pub unsafe fn instr_DB_3_mem(addr: i32) { fpu_fistm32p(addr); } #[no_mangle] @@ -1915,7 +1912,7 @@ pub unsafe fn instr_DC_7_reg(r: i32) { fpu_fdivr(r, fpu_get_sti(r)); } pub unsafe fn instr16_DD_0_mem(addr: i32) { fpu_fldm64(addr); } #[no_mangle] -pub unsafe fn instr16_DD_1_mem(addr: i32) { fpu_fisttp(addr); } +pub unsafe fn instr16_DD_1_mem(addr: i32) { fpu_fisttpm64(addr); } pub unsafe fn instr16_DD_2_mem(addr: i32) { fpu_fstm64(addr); } pub unsafe fn instr16_DD_3_mem(addr: i32) { fpu_fstm64p(addr); } #[no_mangle] @@ -2026,10 +2023,7 @@ pub unsafe fn instr_DE_7_reg(r: i32) { #[no_mangle] pub unsafe fn instr_DF_0_mem(addr: i32) { fpu_fildm16(addr) } #[no_mangle] -pub unsafe fn instr_DF_1_mem(_addr: i32) { - dbg_log!("fisttp"); - fpu_unimpl(); -} +pub unsafe fn instr_DF_1_mem(addr: i32) { fpu_fisttpm16(addr); } pub unsafe fn instr_DF_2_mem(addr: i32) { fpu_fistm16(addr); } pub unsafe fn instr_DF_3_mem(addr: i32) { fpu_fistm16p(addr); } pub unsafe fn instr_DF_4_mem(_addr: i32) { From 5e1985f8aa3e2e336438d35e2af2bbc54edca9d0 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 8 Sep 2023 19:28:16 +0200 Subject: [PATCH 059/180] Update fpu.rs --- src/rust/cpu/fpu.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/rust/cpu/fpu.rs b/src/rust/cpu/fpu.rs index 23e673f3e2..8b8f1d18e7 100644 --- a/src/rust/cpu/fpu.rs +++ b/src/rust/cpu/fpu.rs @@ -326,6 +326,12 @@ pub unsafe fn fpu_fistm16(addr: i32) { safe_write16(addr, v as i32).unwrap(); } #[no_mangle] +pub unsafe fn fpu_fisttpm16(addr: i32) { + return_on_pagefault!(writable_or_pagefault(addr, 2)); + let v = fpu_convert_to_i16(fpu_get_st0()); + safe_write16(addr, v as i32).unwrap(); +} +#[no_mangle] pub unsafe fn fpu_fistm16p(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 2)); let v = fpu_convert_to_i16(fpu_get_st0()); @@ -341,6 +347,12 @@ pub unsafe fn fpu_convert_to_i32(f: F80) -> i32 { x } #[no_mangle] +pub unsafe fn fpu_fisttpm32(addr: i32) { + return_on_pagefault!(writable_or_pagefault(addr, 4)); + let v = fpu_convert_to_i32(fpu_get_st0()); + safe_write32(addr, v).unwrap(); +} +#[no_mangle] pub unsafe fn fpu_fistm32(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 4)); let v = fpu_convert_to_i32(fpu_get_st0()); @@ -368,7 +380,13 @@ pub unsafe fn fpu_fistm64p(addr: i32) { safe_write64(addr, v as u64).unwrap(); fpu_pop(); } - +#[no_mangle] +pub unsafe fn fpu_fisttpm64(addr: i32) { + return_on_pagefault!(writable_or_pagefault(addr, 8)); + let v = fpu_convert_to_i64(fpu_get_st0()); + safe_write64(addr, v as u64).unwrap(); + fpu_pop(); +} #[no_mangle] pub unsafe fn fpu_fldcw(addr: i32) { let word = return_on_pagefault!(safe_read16(addr)) as u16; From 506e90fcde2853746aef1b4bd34a83a6d63c4f2d Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sat, 9 Sep 2023 20:09:25 +0200 Subject: [PATCH 060/180] Update jit_instructions.rs --- src/rust/jit_instructions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/jit_instructions.rs b/src/rust/jit_instructions.rs index 4ac6d28157..8cc20db8c5 100644 --- a/src/rust/jit_instructions.rs +++ b/src/rust/jit_instructions.rs @@ -3854,7 +3854,7 @@ pub fn instr32_DD_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { } pub fn instr16_DD_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { codegen::gen_fpu_load_m64(ctx, modrm_byte); - ctx.builder.call_fn2_i64_i32("fpu_push"); + ctx.builder.call_fn2_i64_i32("fpu_fisttp"); } pub fn instr16_DD_1_reg_jit(ctx: &mut JitContext, r: u32) { codegen::gen_fn1_const(ctx.builder, "fpu_fisttp", r); From 8586b539805cfc785ae5cd492fdb9b1e01812fe6 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sat, 9 Sep 2023 20:50:16 +0200 Subject: [PATCH 061/180] Update x86_table.js\ --- gen/x86_table.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen/x86_table.js b/gen/x86_table.js index 8c7853cb43..ef8f8acdc9 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -324,7 +324,7 @@ const encodings = [ { opcode: 0xDC, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDD, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, - { opcode: 0xDD, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, // fisttp (sse3) + { opcode: 0xDD, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, }, // fisttp (sse3) { opcode: 0xDD, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, { opcode: 0xDD, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, { opcode: 0xDD, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, os: 1, skip_mem: 1 }, // frstor From f584d7b7de37b791bc8a1694911bb38c01e65277 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sat, 9 Sep 2023 21:01:52 +0200 Subject: [PATCH 062/180] Update jit_instructions.rs --- src/rust/jit_instructions.rs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/rust/jit_instructions.rs b/src/rust/jit_instructions.rs index 8cc20db8c5..beca4eeda4 100644 --- a/src/rust/jit_instructions.rs +++ b/src/rust/jit_instructions.rs @@ -3852,17 +3852,6 @@ pub fn instr32_DD_0_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_0_reg_jit pub fn instr32_DD_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { instr16_DD_0_mem_jit(ctx, modrm_byte) } -pub fn instr16_DD_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { - codegen::gen_fpu_load_m64(ctx, modrm_byte); - ctx.builder.call_fn2_i64_i32("fpu_fisttp"); -} -pub fn instr16_DD_1_reg_jit(ctx: &mut JitContext, r: u32) { - codegen::gen_fn1_const(ctx.builder, "fpu_fisttp", r); -} -pub fn instr32_DD_1_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_1_reg_jit(ctx, r) } -pub fn instr32_DD_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { - instr16_DD_1_mem_jit(ctx, modrm_byte) -} pub fn instr16_DD_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { codegen::gen_modrm_resolve(ctx, modrm_byte); let address_local = ctx.builder.set_new_local(); From a758541c22c2744963f8abe34975b6b25e25d9d5 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sun, 10 Sep 2023 13:59:48 +0200 Subject: [PATCH 063/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index a6891a6b4d..f4382f62d9 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1395,8 +1395,14 @@ pub unsafe fn instr_0F37() { // getsec undefined_instruction(); } -#[no_mangle] -pub unsafe fn instr_0F38() { unimplemented_sse(); } +pub unsafe fn instr16_0F38_mem(addr: i32, r: i32) { + cmovcc16(test_o(), return_on_pagefault!(safe_read16(addr)), r); +} +pub unsafe fn instr16_0F38_reg(r1: i32, r: i32) { cmovcc16(test_o(), read_reg16(r1), r); } +pub unsafe fn instr32_0F38_mem(addr: i32, r: i32) { + cmovcc32(test_o(), return_on_pagefault!(safe_read32s(addr)), r); +} +pub unsafe fn instr32_0F38_reg(r1: i32, r: i32) { cmovcc32(test_o(), read_reg32(r1), r); } #[no_mangle] pub unsafe fn instr_0F39() { unimplemented_sse(); } #[no_mangle] From fa892ccc8ec20f22831cd7f3d3cf48c1e24bc906 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Sun, 10 Sep 2023 14:08:35 +0200 Subject: [PATCH 064/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index f4382f62d9..a6891a6b4d 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1395,14 +1395,8 @@ pub unsafe fn instr_0F37() { // getsec undefined_instruction(); } -pub unsafe fn instr16_0F38_mem(addr: i32, r: i32) { - cmovcc16(test_o(), return_on_pagefault!(safe_read16(addr)), r); -} -pub unsafe fn instr16_0F38_reg(r1: i32, r: i32) { cmovcc16(test_o(), read_reg16(r1), r); } -pub unsafe fn instr32_0F38_mem(addr: i32, r: i32) { - cmovcc32(test_o(), return_on_pagefault!(safe_read32s(addr)), r); -} -pub unsafe fn instr32_0F38_reg(r1: i32, r: i32) { cmovcc32(test_o(), read_reg32(r1), r); } +#[no_mangle] +pub unsafe fn instr_0F38() { unimplemented_sse(); } #[no_mangle] pub unsafe fn instr_0F39() { unimplemented_sse(); } #[no_mangle] From 6865409b884ff9250581d8881f917a959f506354 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Mon, 11 Sep 2023 14:07:32 +0200 Subject: [PATCH 065/180] Update Readme.md sse3 support! --- Readme.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Readme.md b/Readme.md index bf6b075218..0a33a4e213 100644 --- a/Readme.md +++ b/Readme.md @@ -5,7 +5,7 @@ WebAssembly modules at runtime in order to achieve decent performance. Here's a list of emulated hardware: - An x86-compatible CPU. The instruction set is around Pentium 4 level, - including full SSE2 support. Some features are missing, in particular: + including full SSE3 support. Some features are missing, in particular: - Task gates, far calls in protected mode - Some 16 bit protected mode features - Single stepping (trap flag, debug registers) @@ -25,7 +25,7 @@ list of emulated hardware: - A generic VGA card with SVGA support and Bochs VBE Extensions. - A PCI bus. This one is partly incomplete and not used by every device. - An IDE disk controller. -- An NE2000 (8390) PCI network card. +- An NE2000 (AKA RTL8390) PCI network card. - A virtio filesystem. - A SoundBlaster 16 sound card. @@ -81,8 +81,7 @@ Here's an overview of the operating systems supported in v86: - FreeDOS, Windows 1.01 and MS-DOS run very well. - KolibriOS works. - Haiku works. -- Android x86 1.6-r2 works if one selects VESA mode at the boot prompt. Newer - versions may work if compiled without SSE3. See [#224](https://github.com/copy/v86/issues/224). +- Android-x86 works up to 4.4-r2. Newer versions halt on a kernel panic error. - Windows 1, 3.x, 95, 98, ME, NT and 2000 work reasonably well. - In Windows 2000 and higher the PC type has to be changed from ACPI PC to Standard PC - There are some known boot issues ([#250](https://github.com/copy/v86/issues/250), [#433](https://github.com/copy/v86/issues/433), [#507](https://github.com/copy/v86/issues/507), [#555](https://github.com/copy/v86/issues/555), [#620](https://github.com/copy/v86/issues/620), [#645](https://github.com/copy/v86/issues/645)) From 261bfe22aab59baa9b3b0dcff918167d93f24589 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 09:54:56 +0200 Subject: [PATCH 066/180] Update fpu.rs --- src/rust/cpu/fpu.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rust/cpu/fpu.rs b/src/rust/cpu/fpu.rs index 8b8f1d18e7..dd46488bf8 100644 --- a/src/rust/cpu/fpu.rs +++ b/src/rust/cpu/fpu.rs @@ -330,6 +330,7 @@ pub unsafe fn fpu_fisttpm16(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 2)); let v = fpu_convert_to_i16(fpu_get_st0()); safe_write16(addr, v as i32).unwrap(); + fpu_pop(); } #[no_mangle] pub unsafe fn fpu_fistm16p(addr: i32) { @@ -351,6 +352,7 @@ pub unsafe fn fpu_fisttpm32(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 4)); let v = fpu_convert_to_i32(fpu_get_st0()); safe_write32(addr, v).unwrap(); + fpu_pop(); } #[no_mangle] pub unsafe fn fpu_fistm32(addr: i32) { From 36eab7116aa28ea35f422301f92cbf4140cdfe82 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 11:50:15 +0200 Subject: [PATCH 067/180] Update fpu.rs --- src/rust/cpu/fpu.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rust/cpu/fpu.rs b/src/rust/cpu/fpu.rs index dd46488bf8..e309aef89e 100644 --- a/src/rust/cpu/fpu.rs +++ b/src/rust/cpu/fpu.rs @@ -328,7 +328,7 @@ pub unsafe fn fpu_fistm16(addr: i32) { #[no_mangle] pub unsafe fn fpu_fisttpm16(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 2)); - let v = fpu_convert_to_i16(fpu_get_st0()); + let v = st0 * fpu_get_sti(1).trunc().two_pow(); safe_write16(addr, v as i32).unwrap(); fpu_pop(); } @@ -350,7 +350,7 @@ pub unsafe fn fpu_convert_to_i32(f: F80) -> i32 { #[no_mangle] pub unsafe fn fpu_fisttpm32(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 4)); - let v = fpu_convert_to_i32(fpu_get_st0()); + let v = st0 * fpu_get_sti(1).trunc().two_pow(); safe_write32(addr, v).unwrap(); fpu_pop(); } @@ -385,7 +385,7 @@ pub unsafe fn fpu_fistm64p(addr: i32) { #[no_mangle] pub unsafe fn fpu_fisttpm64(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 8)); - let v = fpu_convert_to_i64(fpu_get_st0()); + let v = st0 * fpu_get_sti(1).trunc().two_pow(); safe_write64(addr, v as u64).unwrap(); fpu_pop(); } From 03b8872861e5ffaf0439562895872a16868819cc Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 11:54:02 +0200 Subject: [PATCH 068/180] Update fpu.rs --- src/rust/cpu/fpu.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rust/cpu/fpu.rs b/src/rust/cpu/fpu.rs index e309aef89e..b2efb60bab 100644 --- a/src/rust/cpu/fpu.rs +++ b/src/rust/cpu/fpu.rs @@ -328,7 +328,7 @@ pub unsafe fn fpu_fistm16(addr: i32) { #[no_mangle] pub unsafe fn fpu_fisttpm16(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 2)); - let v = st0 * fpu_get_sti(1).trunc().two_pow(); + let v = sti * fpu_get_sti(1).trunc().two_pow(); safe_write16(addr, v as i32).unwrap(); fpu_pop(); } @@ -350,7 +350,7 @@ pub unsafe fn fpu_convert_to_i32(f: F80) -> i32 { #[no_mangle] pub unsafe fn fpu_fisttpm32(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 4)); - let v = st0 * fpu_get_sti(1).trunc().two_pow(); + let v = sti * fpu_get_sti(1).trunc().two_pow(); safe_write32(addr, v).unwrap(); fpu_pop(); } @@ -385,7 +385,7 @@ pub unsafe fn fpu_fistm64p(addr: i32) { #[no_mangle] pub unsafe fn fpu_fisttpm64(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 8)); - let v = st0 * fpu_get_sti(1).trunc().two_pow(); + let v = sti * fpu_get_sti(1).trunc().two_pow(); safe_write64(addr, v as u64).unwrap(); fpu_pop(); } From f34f3fddc8c011dce022757a974bce905465a7f1 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 11:57:47 +0200 Subject: [PATCH 069/180] Update fpu.rs --- src/rust/cpu/fpu.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rust/cpu/fpu.rs b/src/rust/cpu/fpu.rs index b2efb60bab..7de1f576ae 100644 --- a/src/rust/cpu/fpu.rs +++ b/src/rust/cpu/fpu.rs @@ -328,7 +328,7 @@ pub unsafe fn fpu_fistm16(addr: i32) { #[no_mangle] pub unsafe fn fpu_fisttpm16(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 2)); - let v = sti * fpu_get_sti(1).trunc().two_pow(); + let y = st0 * fpu_get_sti(1).trunc().two_pow(); safe_write16(addr, v as i32).unwrap(); fpu_pop(); } @@ -350,7 +350,7 @@ pub unsafe fn fpu_convert_to_i32(f: F80) -> i32 { #[no_mangle] pub unsafe fn fpu_fisttpm32(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 4)); - let v = sti * fpu_get_sti(1).trunc().two_pow(); + let y = st0 * fpu_get_sti(1).trunc().two_pow(); safe_write32(addr, v).unwrap(); fpu_pop(); } @@ -385,7 +385,7 @@ pub unsafe fn fpu_fistm64p(addr: i32) { #[no_mangle] pub unsafe fn fpu_fisttpm64(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 8)); - let v = sti * fpu_get_sti(1).trunc().two_pow(); + let y = st0 * fpu_get_sti(1).trunc().two_pow(); safe_write64(addr, v as u64).unwrap(); fpu_pop(); } From ddabf77766b4200a613881bc6e21f36864161465 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 12:01:04 +0200 Subject: [PATCH 070/180] Update fpu.rs --- src/rust/cpu/fpu.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rust/cpu/fpu.rs b/src/rust/cpu/fpu.rs index 7de1f576ae..e309aef89e 100644 --- a/src/rust/cpu/fpu.rs +++ b/src/rust/cpu/fpu.rs @@ -328,7 +328,7 @@ pub unsafe fn fpu_fistm16(addr: i32) { #[no_mangle] pub unsafe fn fpu_fisttpm16(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 2)); - let y = st0 * fpu_get_sti(1).trunc().two_pow(); + let v = st0 * fpu_get_sti(1).trunc().two_pow(); safe_write16(addr, v as i32).unwrap(); fpu_pop(); } @@ -350,7 +350,7 @@ pub unsafe fn fpu_convert_to_i32(f: F80) -> i32 { #[no_mangle] pub unsafe fn fpu_fisttpm32(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 4)); - let y = st0 * fpu_get_sti(1).trunc().two_pow(); + let v = st0 * fpu_get_sti(1).trunc().two_pow(); safe_write32(addr, v).unwrap(); fpu_pop(); } @@ -385,7 +385,7 @@ pub unsafe fn fpu_fistm64p(addr: i32) { #[no_mangle] pub unsafe fn fpu_fisttpm64(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 8)); - let y = st0 * fpu_get_sti(1).trunc().two_pow(); + let v = st0 * fpu_get_sti(1).trunc().two_pow(); safe_write64(addr, v as u64).unwrap(); fpu_pop(); } From 7cae48b8accf785cf3ffcacb74e4980baa36dead Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 12:04:39 +0200 Subject: [PATCH 071/180] Update fpu.rs --- src/rust/cpu/fpu.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rust/cpu/fpu.rs b/src/rust/cpu/fpu.rs index e309aef89e..dd46488bf8 100644 --- a/src/rust/cpu/fpu.rs +++ b/src/rust/cpu/fpu.rs @@ -328,7 +328,7 @@ pub unsafe fn fpu_fistm16(addr: i32) { #[no_mangle] pub unsafe fn fpu_fisttpm16(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 2)); - let v = st0 * fpu_get_sti(1).trunc().two_pow(); + let v = fpu_convert_to_i16(fpu_get_st0()); safe_write16(addr, v as i32).unwrap(); fpu_pop(); } @@ -350,7 +350,7 @@ pub unsafe fn fpu_convert_to_i32(f: F80) -> i32 { #[no_mangle] pub unsafe fn fpu_fisttpm32(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 4)); - let v = st0 * fpu_get_sti(1).trunc().two_pow(); + let v = fpu_convert_to_i32(fpu_get_st0()); safe_write32(addr, v).unwrap(); fpu_pop(); } @@ -385,7 +385,7 @@ pub unsafe fn fpu_fistm64p(addr: i32) { #[no_mangle] pub unsafe fn fpu_fisttpm64(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 8)); - let v = st0 * fpu_get_sti(1).trunc().two_pow(); + let v = fpu_convert_to_i64(fpu_get_st0()); safe_write64(addr, v as u64).unwrap(); fpu_pop(); } From 05aefa264f3acf70160d732d65f8619ba07dd140 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 12:39:32 +0200 Subject: [PATCH 072/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index a6891a6b4d..2f2f3eb2fa 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -555,15 +555,10 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { } #[no_mangle] pub unsafe fn instr_F20F12(source: reg128, r: i32) { - // movddup xmm, xmm/mem128 + // movddup xmm1, xmm2/mem128 let destination = read_xmm128s(r); let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], - ], + f32: [source.f64[0] as f32, source.f64[1] as f32, 0., 0.], }; write_xmm_reg128(r, result); } @@ -686,15 +681,10 @@ pub unsafe fn instr_660F16_mem(addr: i32, r: i32) { pub unsafe fn instr_660F16_reg(_r1: i32, _r2: i32) { trigger_ud(); } #[no_mangle] pub unsafe fn instr_F30F16(source: reg128, r: i32) { - // movshdup xmm, xmm/mem128 + // movshdup xmm1, xmm2/mem128 let destination = read_xmm128s(r); let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], - ], + f32: [source.f64[0] as f32, source.f64[1] as f32, 0., 0.], }; write_xmm_reg128(r, result); } @@ -1881,7 +1871,7 @@ pub unsafe fn instr_660F7C_mem(addr: i32, r: i32) { } #[no_mangle] pub unsafe fn instr_660F7D(source: reg128, r: i32) { - // hsupbd xmm, xmm/mem128 + // hsupbd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { f32: [ @@ -1920,12 +1910,7 @@ pub unsafe fn instr_F20F7D(source: reg128, r: i32) { // hsubps xmm, xmm/mem128 let destination = read_xmm128s(r); let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], - ], + f32: [source.f64[0] as f32, source.f64[1] as f32, 0., 0.], }; write_xmm_reg128(r, result); } @@ -1950,7 +1935,6 @@ pub unsafe fn instr_0F5A_mem(addr: i32, r: i32) { pub unsafe fn instr_660F5A(source: reg128, r: i32) { // cvtpd2ps xmm1, xmm2/m128 let result = reg128 { - // XXX: These conversions are lossy and should round according to the round control f32: [source.f64[0] as f32, source.f64[1] as f32, 0., 0.], }; write_xmm_reg128(r, result); From 04e3c5d28cccfe1c822011572d8df00956c9d9db Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 12:57:21 +0200 Subject: [PATCH 073/180] Update jit_instructions.rs\ --- src/rust/jit_instructions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/jit_instructions.rs b/src/rust/jit_instructions.rs index beca4eeda4..87ab1ce33c 100644 --- a/src/rust/jit_instructions.rs +++ b/src/rust/jit_instructions.rs @@ -5694,7 +5694,7 @@ pub fn instr_F30F10_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { .store_aligned_i32(global_pointers::get_reg_xmm_offset(r2)); } pub fn instr_F30F12_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { - instr_660F6E_mem_jit(ctx, modrm_byte, r) + sse_read128_xmm_mem(ctx, "instr_660F6E", modrm_byte, r); } pub fn instr_F30F12_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { ctx.builder.const_i32(0); From 0a3cde1be2e45129f10567edce271e68d4b2fd77 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 14:02:18 +0200 Subject: [PATCH 074/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 2f2f3eb2fa..2f721d8bae 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1871,15 +1871,10 @@ pub unsafe fn instr_660F7C_mem(addr: i32, r: i32) { } #[no_mangle] pub unsafe fn instr_660F7D(source: reg128, r: i32) { - // hsupbd xmm1, xmm2/m128 + // hsubpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], - ], + f32: [source.f64[0] as f32, source.f64[1] as f32, 0., 0.], }; write_xmm_reg128(r, result); } From 8293d43b7034d6622ba3229b055d7b4e96146bea Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 14:21:05 +0200 Subject: [PATCH 075/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 44 ++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 2f721d8bae..0163671ff6 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -555,10 +555,10 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { } #[no_mangle] pub unsafe fn instr_F20F12(source: reg128, r: i32) { - // movddup xmm1, xmm2/mem128 + // movddup xmm1, xmm2/m64 let destination = read_xmm128s(r); let result = reg128 { - f32: [source.f64[0] as f32, source.f64[1] as f32, 0., 0.], + f64: [source[0] as f64, source[1] as f64], }; write_xmm_reg128(r, result); } @@ -568,16 +568,15 @@ pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { } #[no_mangle] pub unsafe fn instr_F30F12(source: reg128, r: i32) { - // movsldup xmm, xmm/mem128 + // movsldup xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], + i32: [ + sse_convert_f32_to_i32(source.f32[0]), + sse_convert_f32_to_i32(source.f32[1]), + sse_convert_f32_to_i32(source.f32[2]), + sse_convert_f32_to_i32(source.f32[3]), ], - }; write_xmm_reg128(r, result); } pub unsafe fn instr_F30F12_reg(r1: i32, r2: i32) { instr_F30F12(read_xmm128s(r1), r2); } @@ -681,10 +680,15 @@ pub unsafe fn instr_660F16_mem(addr: i32, r: i32) { pub unsafe fn instr_660F16_reg(_r1: i32, _r2: i32) { trigger_ud(); } #[no_mangle] pub unsafe fn instr_F30F16(source: reg128, r: i32) { - // movshdup xmm1, xmm2/mem128 + // movshdup xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f32: [source.f64[0] as f32, source.f64[1] as f32, 0., 0.], + i32: [ + sse_convert_f32_to_i32(source.f32[0]), + sse_convert_f32_to_i32(source.f32[1]), + sse_convert_f32_to_i32(source.f32[2]), + sse_convert_f32_to_i32(source.f32[3]), + ], }; write_xmm_reg128(r, result); } @@ -1853,15 +1857,10 @@ pub unsafe fn instr_F30F59_mem(addr: i32, r: i32) { } #[no_mangle] pub unsafe fn instr_660F7C(source: reg128, r: i32) { - // haddpd xmm, xmm/mem128 + // haddpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], - ], + f32: [source.f64[0] as f32, source.f64[1] as f32, 0., 0.], }; write_xmm_reg128(r, result); } @@ -1902,10 +1901,15 @@ pub unsafe fn instr_F20F7C_mem(addr: i32, r: i32) { } #[no_mangle] pub unsafe fn instr_F20F7D(source: reg128, r: i32) { - // hsubps xmm, xmm/mem128 + // hsubps xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f32: [source.f64[0] as f32, source.f64[1] as f32, 0., 0.], + i32: [ + sse_convert_f32_to_i32(source.f32[0]), + sse_convert_f32_to_i32(source.f32[1]), + sse_convert_f32_to_i32(source.f32[2]), + sse_convert_f32_to_i32(source.f32[3]), + ], }; write_xmm_reg128(r, result); } From a60aacfdc4dfb7bda2755119658bc652c5ccd26b Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 15:02:19 +0200 Subject: [PATCH 076/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 0163671ff6..99b211eb4d 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -577,6 +577,7 @@ pub unsafe fn instr_F30F12(source: reg128, r: i32) { sse_convert_f32_to_i32(source.f32[2]), sse_convert_f32_to_i32(source.f32[3]), ], + } write_xmm_reg128(r, result); } pub unsafe fn instr_F30F12_reg(r1: i32, r2: i32) { instr_F30F12(read_xmm128s(r1), r2); } From 445ae926aa025fdcb4ebf2b25adf8edda6fb0ea3 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 15:10:10 +0200 Subject: [PATCH 077/180] Update instructions_0f.rs From 062beab6b2db04be4ff2af3f7019223bae4c7e82 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 15:12:46 +0200 Subject: [PATCH 078/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 99b211eb4d..88f7895906 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -577,7 +577,7 @@ pub unsafe fn instr_F30F12(source: reg128, r: i32) { sse_convert_f32_to_i32(source.f32[2]), sse_convert_f32_to_i32(source.f32[3]), ], - } + }; write_xmm_reg128(r, result); } pub unsafe fn instr_F30F12_reg(r1: i32, r2: i32) { instr_F30F12(read_xmm128s(r1), r2); } From 814446b882b65eb7c1178259c27041cdea352d82 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 15:18:13 +0200 Subject: [PATCH 079/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 88f7895906..291c0e2bfe 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -558,7 +558,12 @@ pub unsafe fn instr_F20F12(source: reg128, r: i32) { // movddup xmm1, xmm2/m64 let destination = read_xmm128s(r); let result = reg128 { - f64: [source[0] as f64, source[1] as f64], + i32: [ + sse_convert_f32_to_i32(source.f32[0]), + sse_convert_f32_to_i32(source.f32[1]), + sse_convert_f32_to_i32(source.f32[2]), + sse_convert_f32_to_i32(source.f32[3]), + ], }; write_xmm_reg128(r, result); } From cfc7274de3ed5ece428ab1db4e249eb71ce6b226 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 15:46:46 +0200 Subject: [PATCH 080/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 291c0e2bfe..fec38da012 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1866,7 +1866,12 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { // haddpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f32: [source.f64[0] as f32, source.f64[1] as f32, 0., 0.], + i32: [ + sse_convert_f32_to_i32(source.f32[0]), + sse_convert_f32_to_i32(source.f32[1]), + sse_convert_f32_to_i32(source.f32[2]), + sse_convert_f32_to_i32(source.f32[3]), + ], }; write_xmm_reg128(r, result); } @@ -1879,7 +1884,12 @@ pub unsafe fn instr_660F7D(source: reg128, r: i32) { // hsubpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f32: [source.f64[0] as f32, source.f64[1] as f32, 0., 0.], + i32: [ + sse_convert_f32_to_i32(source.f32[0]), + sse_convert_f32_to_i32(source.f32[1]), + sse_convert_f32_to_i32(source.f32[2]), + sse_convert_f32_to_i32(source.f32[3]), + ], }; write_xmm_reg128(r, result); } From a571b4da9cf7e634ad0b5fe83a9194cc2558e6ea Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 16:15:32 +0200 Subject: [PATCH 081/180] Update fpu.rs --- src/rust/cpu/fpu.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rust/cpu/fpu.rs b/src/rust/cpu/fpu.rs index dd46488bf8..8da07bb97a 100644 --- a/src/rust/cpu/fpu.rs +++ b/src/rust/cpu/fpu.rs @@ -328,7 +328,7 @@ pub unsafe fn fpu_fistm16(addr: i32) { #[no_mangle] pub unsafe fn fpu_fisttpm16(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 2)); - let v = fpu_convert_to_i16(fpu_get_st0()); + let v = st0 * fpu_get_sti(1).trunc().two_pow(); safe_write16(addr, v as i32).unwrap(); fpu_pop(); } @@ -350,14 +350,14 @@ pub unsafe fn fpu_convert_to_i32(f: F80) -> i32 { #[no_mangle] pub unsafe fn fpu_fisttpm32(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 4)); - let v = fpu_convert_to_i32(fpu_get_st0()); + let v = st0 * fpu_get_sti(1).trunc().two_pow(); safe_write32(addr, v).unwrap(); fpu_pop(); } #[no_mangle] pub unsafe fn fpu_fistm32(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 4)); - let v = fpu_convert_to_i32(fpu_get_st0()); + let v = st0 * fpu_get_sti(1).trunc().two_pow(); safe_write32(addr, v).unwrap(); } #[no_mangle] @@ -385,7 +385,7 @@ pub unsafe fn fpu_fistm64p(addr: i32) { #[no_mangle] pub unsafe fn fpu_fisttpm64(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 8)); - let v = fpu_convert_to_i64(fpu_get_st0()); + let v = st0 * fpu_get_sti(1).trunc().two_pow(); safe_write64(addr, v as u64).unwrap(); fpu_pop(); } From 6598bd268353fea118c6c97750de7d1ee07c4966 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 16:17:25 +0200 Subject: [PATCH 082/180] Update fpu.rs --- src/rust/cpu/fpu.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rust/cpu/fpu.rs b/src/rust/cpu/fpu.rs index 8da07bb97a..da8aeb56b2 100644 --- a/src/rust/cpu/fpu.rs +++ b/src/rust/cpu/fpu.rs @@ -328,7 +328,7 @@ pub unsafe fn fpu_fistm16(addr: i32) { #[no_mangle] pub unsafe fn fpu_fisttpm16(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 2)); - let v = st0 * fpu_get_sti(1).trunc().two_pow(); + let v = fpu_convert_to_i32(fpu_get_st0()); safe_write16(addr, v as i32).unwrap(); fpu_pop(); } @@ -350,14 +350,14 @@ pub unsafe fn fpu_convert_to_i32(f: F80) -> i32 { #[no_mangle] pub unsafe fn fpu_fisttpm32(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 4)); - let v = st0 * fpu_get_sti(1).trunc().two_pow(); + let v = fpu_convert_to_i32(fpu_get_st0()); safe_write32(addr, v).unwrap(); fpu_pop(); } #[no_mangle] pub unsafe fn fpu_fistm32(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 4)); - let v = st0 * fpu_get_sti(1).trunc().two_pow(); + let v = fpu_convert_to_i32(fpu_get_st0()); safe_write32(addr, v).unwrap(); } #[no_mangle] @@ -385,7 +385,7 @@ pub unsafe fn fpu_fistm64p(addr: i32) { #[no_mangle] pub unsafe fn fpu_fisttpm64(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 8)); - let v = st0 * fpu_get_sti(1).trunc().two_pow(); + let v = fpu_convert_to_i32(fpu_get_st0()); safe_write64(addr, v as u64).unwrap(); fpu_pop(); } From 1b377ed9668af7aa69b9b69f5a2ba04c3f821539 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 17:34:00 +0200 Subject: [PATCH 083/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index fec38da012..1f3b7d744c 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1866,11 +1866,11 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { // haddpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - i32: [ - sse_convert_f32_to_i32(source.f32[0]), - sse_convert_f32_to_i32(source.f32[1]), - sse_convert_f32_to_i32(source.f32[2]), - sse_convert_f32_to_i32(source.f32[3]), + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], ], }; write_xmm_reg128(r, result); @@ -1884,11 +1884,11 @@ pub unsafe fn instr_660F7D(source: reg128, r: i32) { // hsubpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - i32: [ - sse_convert_f32_to_i32(source.f32[0]), - sse_convert_f32_to_i32(source.f32[1]), - sse_convert_f32_to_i32(source.f32[2]), - sse_convert_f32_to_i32(source.f32[3]), + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], ], }; write_xmm_reg128(r, result); @@ -1920,11 +1920,11 @@ pub unsafe fn instr_F20F7D(source: reg128, r: i32) { // hsubps xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - i32: [ - sse_convert_f32_to_i32(source.f32[0]), - sse_convert_f32_to_i32(source.f32[1]), - sse_convert_f32_to_i32(source.f32[2]), - sse_convert_f32_to_i32(source.f32[3]), + f32: [ + destination.f32[0] - destination.f32[1], + destination.f32[2] - destination.f32[3], + source.f32[0] - source.f32[1], + source.f32[2] - source.f32[3], ], }; write_xmm_reg128(r, result); From c6e902a7e02f0621de2590de2fe42b8fcc0f23c1 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 17:45:09 +0200 Subject: [PATCH 084/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 1f3b7d744c..c4d7ee14cf 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1867,10 +1867,10 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], + destination.f32[0] + destination.f32[1] * 2, + destination.f32[2] + destination.f32[3] * 2, + source.f32[0] + source.f32[1] * 2, + source.f32[2] + source.f32[3] * 2, ], }; write_xmm_reg128(r, result); From 6e56f1a349ce9d56169c32694a7b392aaab5fe59 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 17:48:45 +0200 Subject: [PATCH 085/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index c4d7ee14cf..171e65a7d0 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1867,10 +1867,10 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f32: [ - destination.f32[0] + destination.f32[1] * 2, - destination.f32[2] + destination.f32[3] * 2, - source.f32[0] + source.f32[1] * 2, - source.f32[2] + source.f32[3] * 2, + destination.f32[0] + destination.f32[1] * 2.0, + destination.f32[2] + destination.f32[3] * 2.0, + source.f32[0] + source.f32[1] * 2.0, + source.f32[2] + source.f32[3] * 2.0, ], }; write_xmm_reg128(r, result); From e72da4d17895959cb4a85a8f57b583726df4a8b9 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 18:04:08 +0200 Subject: [PATCH 086/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 171e65a7d0..e0d383c491 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1867,10 +1867,10 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f32: [ - destination.f32[0] + destination.f32[1] * 2.0, - destination.f32[2] + destination.f32[3] * 2.0, - source.f32[0] + source.f32[1] * 2.0, - source.f32[2] + source.f32[3] * 2.0, + destination.f32[1] + destination.f32[2], + destination.f32[4] + destination.f32[6], + source.f32[1] + source.f32[2], + source.f32[4] + source.f32[6], ], }; write_xmm_reg128(r, result); From e21376a755cfcadedd6a0338c0339de338005043 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 18:09:14 +0200 Subject: [PATCH 087/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index e0d383c491..1a9ad8a262 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1867,10 +1867,10 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f32: [ - destination.f32[1] + destination.f32[2], - destination.f32[4] + destination.f32[6], + destination.f32[1] + destination.f32[1], + destination.f32[3] + destination.f32[4], source.f32[1] + source.f32[2], - source.f32[4] + source.f32[6], + source.f32[3] + source.f32[4], ], }; write_xmm_reg128(r, result); From 942dc20622717aebee0688e58611c7cbc3c71b47 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 18:11:46 +0200 Subject: [PATCH 088/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 1a9ad8a262..1f3b7d744c 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1867,10 +1867,10 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f32: [ - destination.f32[1] + destination.f32[1], - destination.f32[3] + destination.f32[4], - source.f32[1] + source.f32[2], - source.f32[3] + source.f32[4], + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], ], }; write_xmm_reg128(r, result); From c0c98262d075e67717b5d6a2b168a4b810554a99 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 18:28:14 +0200 Subject: [PATCH 089/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 1f3b7d744c..4183e62505 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1873,7 +1873,7 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { source.f32[2] + source.f32[3], ], }; - write_xmm_reg128(r, result); + write_xmm_reg128(r, result * 2.0); } pub unsafe fn instr_660F7C_reg(r1: i32, r2: i32) { instr_660F7C(read_xmm128s(r1), r2); } pub unsafe fn instr_660F7C_mem(addr: i32, r: i32) { From 7ed6ac06d82e9e8aae2152585a47755fec27dc68 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 18:35:51 +0200 Subject: [PATCH 090/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 4183e62505..1f3b7d744c 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1873,7 +1873,7 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { source.f32[2] + source.f32[3], ], }; - write_xmm_reg128(r, result * 2.0); + write_xmm_reg128(r, result); } pub unsafe fn instr_660F7C_reg(r1: i32, r2: i32) { instr_660F7C(read_xmm128s(r1), r2); } pub unsafe fn instr_660F7C_mem(addr: i32, r: i32) { From 79822eae6c50f26c92b85a224253d02dd2bfcf54 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 18:37:35 +0200 Subject: [PATCH 091/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 1f3b7d744c..0950378e9e 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1866,11 +1866,9 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { // haddpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], + f64: [ + source.f64[0] + destination.f64[0], + source.f64[1] + destination.f64[1], ], }; write_xmm_reg128(r, result); From 06944b08b01ea3e2e3783aa0e0a5b64238f191a4 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 18:53:15 +0200 Subject: [PATCH 092/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 0950378e9e..bda3da7b46 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1866,9 +1866,9 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { // haddpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f64: [ - source.f64[0] + destination.f64[0], - source.f64[1] + destination.f64[1], + f32: [ + source.f32[0] + destination.f32[0], + source.f32[1] + destination.f32[1], ], }; write_xmm_reg128(r, result); From 9142373b978aa28bcb5416148a04709b6315e4f0 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 18:57:54 +0200 Subject: [PATCH 093/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index bda3da7b46..92e48fae8a 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1867,8 +1867,8 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f32: [ - source.f32[0] + destination.f32[0], - source.f32[1] + destination.f32[1], + source.f64[0] + destination.f64[0], + source.f64[1] + destination.f64[1], ], }; write_xmm_reg128(r, result); From 6a076d994490f4cd4064f51c8c07b102591f3b50 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 19:06:47 +0200 Subject: [PATCH 094/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 92e48fae8a..0870260fe6 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -558,11 +558,11 @@ pub unsafe fn instr_F20F12(source: reg128, r: i32) { // movddup xmm1, xmm2/m64 let destination = read_xmm128s(r); let result = reg128 { - i32: [ - sse_convert_f32_to_i32(source.f32[0]), - sse_convert_f32_to_i32(source.f32[1]), - sse_convert_f32_to_i32(source.f32[2]), - sse_convert_f32_to_i32(source.f32[3]), + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], ], }; write_xmm_reg128(r, result); @@ -576,11 +576,11 @@ pub unsafe fn instr_F30F12(source: reg128, r: i32) { // movsldup xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - i32: [ - sse_convert_f32_to_i32(source.f32[0]), - sse_convert_f32_to_i32(source.f32[1]), - sse_convert_f32_to_i32(source.f32[2]), - sse_convert_f32_to_i32(source.f32[3]), + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], ], }; write_xmm_reg128(r, result); @@ -689,11 +689,11 @@ pub unsafe fn instr_F30F16(source: reg128, r: i32) { // movshdup xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - i32: [ - sse_convert_f32_to_i32(source.f32[0]), - sse_convert_f32_to_i32(source.f32[1]), - sse_convert_f32_to_i32(source.f32[2]), - sse_convert_f32_to_i32(source.f32[3]), + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], ], }; write_xmm_reg128(r, result); From c41226cd9bedb363c606819715fec0a3aca55e91 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 19:08:46 +0200 Subject: [PATCH 095/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 0870260fe6..f6df9ab301 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1867,8 +1867,8 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f32: [ - source.f64[0] + destination.f64[0], - source.f64[1] + destination.f64[1], + source.f32[0] + destination.f32[0], + source.f32[1] + destination.f32[1], ], }; write_xmm_reg128(r, result); From 7a9ea67d960107768c1bc0300fecb73d1dcfc003 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 19:15:14 +0200 Subject: [PATCH 096/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index f6df9ab301..b4d30e8b65 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1866,9 +1866,9 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { // haddpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f32: [ - source.f32[0] + destination.f32[0], - source.f32[1] + destination.f32[1], + f64: [ + source.f64[0] * destination.f64[0], + source.f64[1] * destination.f64[1], ], }; write_xmm_reg128(r, result); From 92f7ca134ff864f4827004549828b93e187589f8 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 19:18:29 +0200 Subject: [PATCH 097/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index b4d30e8b65..e2457f8ddd 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1867,8 +1867,10 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - source.f64[0] * destination.f64[0], - source.f64[1] * destination.f64[1], + destination.f64[0] + destination.f64[1], + destination.f64[2] + destination.f64[3], + source.f64[0] + source.f64[1], + source.f64[2] + source.f64[3], ], }; write_xmm_reg128(r, result); From d49d32b91e1f1898bcbdea0213a0d686b9771ebe Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 19:21:44 +0200 Subject: [PATCH 098/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index e2457f8ddd..ce95ebb2ae 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1866,11 +1866,11 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { // haddpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f64: [ - destination.f64[0] + destination.f64[1], - destination.f64[2] + destination.f64[3], - source.f64[0] + source.f64[1], - source.f64[2] + source.f64[3], + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], ], }; write_xmm_reg128(r, result); @@ -1884,11 +1884,9 @@ pub unsafe fn instr_660F7D(source: reg128, r: i32) { // hsubpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], + f64: [ + destination.f64[0] + source.f64[0], + destination.f64[1] + source.f64[1], ], }; write_xmm_reg128(r, result); From d8b307a6737c16f3e583ca9544d0043e73753054 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 19:34:59 +0200 Subject: [PATCH 099/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index ce95ebb2ae..c5e4adb051 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1866,11 +1866,9 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { // haddpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], + f64: [ + destination.f64[0] + source.f64[0], + destination.f64[1] + source.f64[1], ], }; write_xmm_reg128(r, result); From aeaa1f2aa798f6148fc96abaefd6b3b3481aff15 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 20:16:51 +0200 Subject: [PATCH 100/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index c5e4adb051..a6b3c8c89c 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1866,9 +1866,11 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { // haddpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f64: [ - destination.f64[0] + source.f64[0], - destination.f64[1] + source.f64[1], + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[1] + destination.f32[2], + source.f32[0] + source.f32[1], + source.f32[1] + source.f32[2], ], }; write_xmm_reg128(r, result); From f6871d8f58a24e04841ea4506a8a1a8bdaf58833 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 20:40:23 +0200 Subject: [PATCH 101/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index a6b3c8c89c..ddff33b06e 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1866,11 +1866,9 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { // haddpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[1] + destination.f32[2], - source.f32[0] + source.f32[1], - source.f32[1] + source.f32[2], + f64: [ + destination.f64[0] + source.f64[1], + destination.f64[2] + source.f64[3], ], }; write_xmm_reg128(r, result); @@ -1885,8 +1883,8 @@ pub unsafe fn instr_660F7D(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - destination.f64[0] + source.f64[0], - destination.f64[1] + source.f64[1], + destination.f64[0] - source.f64[0], + destination.f64[1] - source.f64[1], ], }; write_xmm_reg128(r, result); From 9e4816e0fc0870ec5a23082690feeb62b91f539d Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 20:47:24 +0200 Subject: [PATCH 102/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index ddff33b06e..74ee08ad4e 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1868,7 +1868,7 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { let result = reg128 { f64: [ destination.f64[0] + source.f64[1], - destination.f64[2] + source.f64[3], + destination.f64[1] + source.f64[2], ], }; write_xmm_reg128(r, result); @@ -1883,8 +1883,8 @@ pub unsafe fn instr_660F7D(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - destination.f64[0] - source.f64[0], - destination.f64[1] - source.f64[1], + destination.f64[0] - source.f64[1], + destination.f64[1] - source.f64[2], ], }; write_xmm_reg128(r, result); From 039cf9cc72838a1ac079f494c0c092803b60e544 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Tue, 12 Sep 2023 20:52:28 +0200 Subject: [PATCH 103/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 74ee08ad4e..eb71d83ae0 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1868,7 +1868,7 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { let result = reg128 { f64: [ destination.f64[0] + source.f64[1], - destination.f64[1] + source.f64[2], + destination.f64[1] + source.f64[1], ], }; write_xmm_reg128(r, result); @@ -1884,7 +1884,7 @@ pub unsafe fn instr_660F7D(source: reg128, r: i32) { let result = reg128 { f64: [ destination.f64[0] - source.f64[1], - destination.f64[1] - source.f64[2], + destination.f64[1] - source.f64[1], ], }; write_xmm_reg128(r, result); From 143b3b4c0b4e56c7fc53d56f9dbd2a889c53deef Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 09:26:35 +0200 Subject: [PATCH 104/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index eb71d83ae0..96a2438985 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1866,9 +1866,11 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { // haddpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f64: [ - destination.f64[0] + source.f64[1], - destination.f64[1] + source.f64[1], + f32: [ + destination.f32[0] + destination.f32[1] * 2, + destination.f32[2] + destination.f32[3] * 2, + source.f32[0] + source.f32[1] * 2, + source.f32[2] + source.f32[3] * 2, ], }; write_xmm_reg128(r, result); From 5a18e65daee8e84917e063a3e425419382ffcc4b Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 09:30:26 +0200 Subject: [PATCH 105/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 96a2438985..bdca2c195b 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1,4 +1,4 @@ -#![allow(non_snake_case)] +f#![allow(non_snake_case)] extern "C" { fn get_rand_int() -> i32; @@ -1867,10 +1867,10 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f32: [ - destination.f32[0] + destination.f32[1] * 2, - destination.f32[2] + destination.f32[3] * 2, - source.f32[0] + source.f32[1] * 2, - source.f32[2] + source.f32[3] * 2, + destination.f32[0] + destination.f32[1] * 2.0, + destination.f32[2] + destination.f32[3] * 2.0, + source.f32[0] + source.f32[1] * 2.0, + source.f32[2] + source.f32[3] * 2.0, ], }; write_xmm_reg128(r, result); From 6f56245e99aabd3528480d5c558234f448bf541a Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 09:34:25 +0200 Subject: [PATCH 106/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index bdca2c195b..f26a56e120 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1866,11 +1866,9 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { // haddpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1] * 2.0, - destination.f32[2] + destination.f32[3] * 2.0, - source.f32[0] + source.f32[1] * 2.0, - source.f32[2] + source.f32[3] * 2.0, + f64: [ + destination.f64[0] + source.f64[0], + destination.f64[1] + source.f64[1], ], }; write_xmm_reg128(r, result); From e724a3cb32ea3879e4ac82c585242ec02efd8bf6 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 09:37:16 +0200 Subject: [PATCH 107/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index f26a56e120..eb71d83ae0 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1,4 +1,4 @@ -f#![allow(non_snake_case)] +#![allow(non_snake_case)] extern "C" { fn get_rand_int() -> i32; @@ -1867,7 +1867,7 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - destination.f64[0] + source.f64[0], + destination.f64[0] + source.f64[1], destination.f64[1] + source.f64[1], ], }; From eae5042e37a87bb3ff06955cacb83efdb053e4a1 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 10:52:59 +0200 Subject: [PATCH 108/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index eb71d83ae0..09a4db59a1 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -558,11 +558,9 @@ pub unsafe fn instr_F20F12(source: reg128, r: i32) { // movddup xmm1, xmm2/m64 let destination = read_xmm128s(r); let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], + f64: [ + destination.f32[0] + source.f32[1], + destination.f32[2] + source.f32[3], ], }; write_xmm_reg128(r, result); From fbb8aee807edcfdba2e7a9e8d0b721cf17a2654b Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 10:57:20 +0200 Subject: [PATCH 109/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 09a4db59a1..32ee45d1f1 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -559,8 +559,8 @@ pub unsafe fn instr_F20F12(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - destination.f32[0] + source.f32[1], - destination.f32[2] + source.f32[3], + destination.f64[0] + source.f64[1], + destination.f64[2] + source.f64[3], ], }; write_xmm_reg128(r, result); From 100ff3d7f8dcdba20d38f44ed3957a1718f72ee0 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 10:59:36 +0200 Subject: [PATCH 110/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 32ee45d1f1..38c0d24bd9 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1880,9 +1880,11 @@ pub unsafe fn instr_660F7D(source: reg128, r: i32) { // hsubpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f64: [ - destination.f64[0] - source.f64[1], - destination.f64[1] - source.f64[1], + f32: [ + destination.f32[0] - destination.f32[1], + destination.f32[2] - destination.f32[3], + source.f32[0] - source.f32[1], + source.f32[2] - source.f32[3], ], }; write_xmm_reg128(r, result); @@ -1914,11 +1916,9 @@ pub unsafe fn instr_F20F7D(source: reg128, r: i32) { // hsubps xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f32: [ - destination.f32[0] - destination.f32[1], - destination.f32[2] - destination.f32[3], - source.f32[0] - source.f32[1], - source.f32[2] - source.f32[3], + f64: [ + destination.f64[0] - source.f64[1], + destination.f64[1] - source.f64[1], ], }; write_xmm_reg128(r, result); From 94e4a779bcbda5a385e99aec8f23b6167a1d6bc1 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 11:01:54 +0200 Subject: [PATCH 111/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 38c0d24bd9..8d07adfddd 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -560,7 +560,7 @@ pub unsafe fn instr_F20F12(source: reg128, r: i32) { let result = reg128 { f64: [ destination.f64[0] + source.f64[1], - destination.f64[2] + source.f64[3], + destination.f64[1] + source.f64[1], ], }; write_xmm_reg128(r, result); From d58e119b31444f81ac0c73d54c76b60adbc023ca Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 11:14:06 +0200 Subject: [PATCH 112/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 8d07adfddd..27941d6dc0 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1880,11 +1880,9 @@ pub unsafe fn instr_660F7D(source: reg128, r: i32) { // hsubpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f32: [ - destination.f32[0] - destination.f32[1], - destination.f32[2] - destination.f32[3], - source.f32[0] - source.f32[1], - source.f32[2] - source.f32[3], + f64: [ + destination.f64[0] - source.f64[1], + destination.f64[1] - source.f64[1], ], }; write_xmm_reg128(r, result); @@ -1916,9 +1914,11 @@ pub unsafe fn instr_F20F7D(source: reg128, r: i32) { // hsubps xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f64: [ - destination.f64[0] - source.f64[1], - destination.f64[1] - source.f64[1], + f32: [ + destination.f32[0] - destination.f32[1], + destination.f32[2] - destination.f32[3], + source.f32[0] - source.f32[1], + source.f32[2] - source.f32[3], ], }; write_xmm_reg128(r, result); From daf180e5fba0ea96caad44ee8d28eb1c8297136b Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 12:41:45 +0200 Subject: [PATCH 113/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 27941d6dc0..a271bc562f 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -687,11 +687,9 @@ pub unsafe fn instr_F30F16(source: reg128, r: i32) { // movshdup xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], + f64: [ + destination.f64[0] + source.f64[1], + destination.f64[1] + source.f64[1], ], }; write_xmm_reg128(r, result); From d901901d6cffa2634a477d592d66e5f9b4ebe13e Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 12:55:43 +0200 Subject: [PATCH 114/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index a271bc562f..41ef2356f7 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -574,11 +574,9 @@ pub unsafe fn instr_F30F12(source: reg128, r: i32) { // movsldup xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], + f64: [ + source.f64[1] + destination.f64[2] + source.f64[2] + destination.f64[1] ], }; write_xmm_reg128(r, result); @@ -688,8 +686,8 @@ pub unsafe fn instr_F30F16(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - destination.f64[0] + source.f64[1], - destination.f64[1] + source.f64[1], + source.f64[1] + destination.f64[2] + source.f64[2] + destination.f64[1] ], }; write_xmm_reg128(r, result); From 9db68509cf669397f75a2a3d6515767cf6f27c44 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 12:58:24 +0200 Subject: [PATCH 115/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 41ef2356f7..29c23fdfe8 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -575,8 +575,8 @@ pub unsafe fn instr_F30F12(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - source.f64[1] + destination.f64[2] - source.f64[2] + destination.f64[1] + source.f64[1] + destination.f64[2], + source.f64[2] + destination.f64[1], ], }; write_xmm_reg128(r, result); @@ -686,8 +686,8 @@ pub unsafe fn instr_F30F16(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - source.f64[1] + destination.f64[2] - source.f64[2] + destination.f64[1] + source.f64[1] + destination.f64[2], + source.f64[2] + destination.f64[1], ], }; write_xmm_reg128(r, result); From 028a9588edfb0c2fa1a8feb9bc0bb7b38714d7a9 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 13:01:28 +0200 Subject: [PATCH 116/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 29c23fdfe8..0d167de98e 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -575,8 +575,8 @@ pub unsafe fn instr_F30F12(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - source.f64[1] + destination.f64[2], - source.f64[2] + destination.f64[1], + source.f64[1] + destination.f64[1], + source.f64[1] + destination.f64[1], ], }; write_xmm_reg128(r, result); @@ -686,8 +686,8 @@ pub unsafe fn instr_F30F16(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - source.f64[1] + destination.f64[2], - source.f64[2] + destination.f64[1], + source.f64[1] + destination.f64[1], + source.f64[1] + destination.f64[1], ], }; write_xmm_reg128(r, result); From 4512d2263c47a821f80395e4bf18d8364aa7f345 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 15:13:08 +0200 Subject: [PATCH 117/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 0d167de98e..afbc38d7b8 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1860,9 +1860,11 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { // haddpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f64: [ - destination.f64[0] + source.f64[1], - destination.f64[1] + source.f64[1], + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], ], }; write_xmm_reg128(r, result); @@ -1893,10 +1895,8 @@ pub unsafe fn instr_F20F7C(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], + destination.f64[1] + source.f64[1], + destination.f64[1] + source.f64[1], ], }; write_xmm_reg128(r, result); From 586fc837a9661940b8418643501588858b11d45e Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 15:17:53 +0200 Subject: [PATCH 118/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index afbc38d7b8..6be9040ae6 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1894,7 +1894,7 @@ pub unsafe fn instr_F20F7C(source: reg128, r: i32) { // haddps xmm, xmm/mem128 let destination = read_xmm128s(r); let result = reg128 { - f32: [ + f62: [ destination.f64[1] + source.f64[1], destination.f64[1] + source.f64[1], ], From 72210ac3883e6ae18cd873d22bf2281f45f05e04 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 15:21:40 +0200 Subject: [PATCH 119/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 6be9040ae6..d968d0a73f 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1894,7 +1894,7 @@ pub unsafe fn instr_F20F7C(source: reg128, r: i32) { // haddps xmm, xmm/mem128 let destination = read_xmm128s(r); let result = reg128 { - f62: [ + f64: [ destination.f64[1] + source.f64[1], destination.f64[1] + source.f64[1], ], From 43a014250eb7207e063146aa1ebfe285cb733d92 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 15:41:00 +0200 Subject: [PATCH 120/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index d968d0a73f..1058172737 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1860,11 +1860,9 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { // haddpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], + f64: [ + destination.f64[1] + source.f64[1], + destination.f64[1] + source.f64[1], ], }; write_xmm_reg128(r, result); @@ -1894,9 +1892,11 @@ pub unsafe fn instr_F20F7C(source: reg128, r: i32) { // haddps xmm, xmm/mem128 let destination = read_xmm128s(r); let result = reg128 { - f64: [ - destination.f64[1] + source.f64[1], - destination.f64[1] + source.f64[1], + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], ], }; write_xmm_reg128(r, result); From 0b6cf41ab77301516499629634976f75c33619a5 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 16:11:07 +0200 Subject: [PATCH 121/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 1058172737..6dc0444563 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -685,9 +685,9 @@ pub unsafe fn instr_F30F16(source: reg128, r: i32) { // movshdup xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f64: [ - source.f64[1] + destination.f64[1], - source.f64[1] + destination.f64[1], + f64: [ + destination.f64[0] - source.f64[1], + destination.f64[1] - source.f64[1], ], }; write_xmm_reg128(r, result); From 8c5b14135a0be33ab6e304b58f512ece2dcb9545 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 16:13:05 +0200 Subject: [PATCH 122/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 6dc0444563..6e59d78516 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1,4 +1,7 @@ -#![allow(non_snake_case)] + f64: [ + destination.f64[0] - source.f64[1], + destination.f64[1] - source.f64[1], + ],#![allow(non_snake_case)] extern "C" { fn get_rand_int() -> i32; @@ -574,9 +577,9 @@ pub unsafe fn instr_F30F12(source: reg128, r: i32) { // movsldup xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f64: [ - source.f64[1] + destination.f64[1], - source.f64[1] + destination.f64[1], + f64: [ + destination.f64[0] - source.f64[1], + destination.f64[1] - source.f64[0], ], }; write_xmm_reg128(r, result); @@ -686,8 +689,8 @@ pub unsafe fn instr_F30F16(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ + destination.f64[1] - source.f64[0], destination.f64[0] - source.f64[1], - destination.f64[1] - source.f64[1], ], }; write_xmm_reg128(r, result); From 7c23424baca982930372877b5afbada681aa735e Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 16:16:21 +0200 Subject: [PATCH 123/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 6e59d78516..355d03f552 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1,8 +1,3 @@ - f64: [ - destination.f64[0] - source.f64[1], - destination.f64[1] - source.f64[1], - ],#![allow(non_snake_case)] - extern "C" { fn get_rand_int() -> i32; } From a29798f761131a82d713f82be61ec6fad471f2b3 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 16:26:55 +0200 Subject: [PATCH 124/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 355d03f552..dbbf50267f 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1859,8 +1859,8 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - destination.f64[1] + source.f64[1], - destination.f64[1] + source.f64[1], + source.f64[0] + destination.f64[0], + source.f64[1] + destination.f64[1], ], }; write_xmm_reg128(r, result); From f2a531cf1639b45cd33284ee11bdfc718b9bd65d Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 17:46:25 +0200 Subject: [PATCH 125/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index dbbf50267f..255e9470f4 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1858,9 +1858,9 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { // haddpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f64: [ - source.f64[0] + destination.f64[0], - source.f64[1] + destination.f64[1], + f64: [ + destination.f64[0] + source.f64[1], + destination.f64[1] + source.f64[1], ], }; write_xmm_reg128(r, result); From b915efdfe0f35591c9032f3c87ff746f8ad2dd6d Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 19:15:08 +0200 Subject: [PATCH 126/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 255e9470f4..e24a1ad1c4 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -683,9 +683,11 @@ pub unsafe fn instr_F30F16(source: reg128, r: i32) { // movshdup xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f64: [ - destination.f64[1] - source.f64[0], - destination.f64[0] - source.f64[1], + f32: [ + destination.f32[0] + source.f32[1], + destination.f32[1] + source.f32[1], + destination.f32[2] + source.f32[3], + destination.f32[3] + source.f32[3], ], }; write_xmm_reg128(r, result); @@ -1859,7 +1861,7 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - destination.f64[0] + source.f64[1], + destination.f64[1] + source.f64[1], destination.f64[1] + source.f64[1], ], }; @@ -1875,7 +1877,7 @@ pub unsafe fn instr_660F7D(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - destination.f64[0] - source.f64[1], + destination.f64[1] - source.f64[1], destination.f64[1] - source.f64[1], ], }; From 07c6d812482b497436792adad4bd12344e8e4203 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 19:33:01 +0200 Subject: [PATCH 127/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index e24a1ad1c4..ec422b1447 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1861,8 +1861,8 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - destination.f64[1] + source.f64[1], - destination.f64[1] + source.f64[1], + destination.f64[0] + source.f64[1], + destination.f64[0] + source.f64[1], ], }; write_xmm_reg128(r, result); From a10090b3f0e7d6ed1a0b20bcbb43c25ff3038d38 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 19:53:11 +0200 Subject: [PATCH 128/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index ec422b1447..0740e95e67 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1860,9 +1860,9 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { // haddpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f64: [ - destination.f64[0] + source.f64[1], - destination.f64[0] + source.f64[1], + f64: [ + source.f64[0] + destination.f64[1], + source.f64[0] + destination.f64[1], ], }; write_xmm_reg128(r, result); @@ -1876,9 +1876,9 @@ pub unsafe fn instr_660F7D(source: reg128, r: i32) { // hsubpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f64: [ - destination.f64[1] - source.f64[1], - destination.f64[1] - source.f64[1], + f64: [ + source.f64[0] - destination.f64[1], + source.f64[0] - destination.f64[1], ], }; write_xmm_reg128(r, result); From d78231714c29c64bb66eb35838eb54f6b23d9cba Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 20:13:11 +0200 Subject: [PATCH 129/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 0740e95e67..6c9c7ffbd1 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -557,8 +557,8 @@ pub unsafe fn instr_F20F12(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - destination.f64[0] + source.f64[1], - destination.f64[1] + source.f64[1], + destination.f64[0] + source.f64[0], + destination.f64[1] + source.f64[0], ], }; write_xmm_reg128(r, result); @@ -572,9 +572,11 @@ pub unsafe fn instr_F30F12(source: reg128, r: i32) { // movsldup xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f64: [ - destination.f64[0] - source.f64[1], - destination.f64[1] - source.f64[0], + f32: [ + destination.f32[0] + source.f32[0], + destination.f32[1] + source.f32[0], + destination.f32[2] + source.f32[2], + destination.f32[3] + source.f32[2], ], }; write_xmm_reg128(r, result); From 3426055587870b3b32e85552c21d02eef9b36505 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 20:56:14 +0200 Subject: [PATCH 130/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 6c9c7ffbd1..bf51907120 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1863,8 +1863,8 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - source.f64[0] + destination.f64[1], - source.f64[0] + destination.f64[1], + source.f64[0] + source.f64[1], + source.f64[0] + source.f64[1], ], }; write_xmm_reg128(r, result); From 11c874bda2643bde66272a1855df6e5023059147 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Wed, 13 Sep 2023 21:10:46 +0200 Subject: [PATCH 131/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index bf51907120..0e92459d8c 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1862,9 +1862,11 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { // haddpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f64: [ - source.f64[0] + source.f64[1], - source.f64[0] + source.f64[1], + f32: [ + destination.f32[0] * destination.f32[1], + destination.f32[2] * destination.f32[3], + source.f32[0] * source.f32[1], + source.f32[2] * source.f32[3], ], }; write_xmm_reg128(r, result); From 158a4d27aeca7bc6b210ae2164268079711c8651 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 13:02:59 +0200 Subject: [PATCH 132/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 0e92459d8c..a8a9716a80 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1862,11 +1862,9 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { // haddpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f32: [ - destination.f32[0] * destination.f32[1], - destination.f32[2] * destination.f32[3], - source.f32[0] * source.f32[1], - source.f32[2] * source.f32[3], + f64: [ + source.f64[1] + source.f64[0], + source.f64[1] + source.f64[0], ], }; write_xmm_reg128(r, result); From aaf305d3ff338f511c12be3bfe904ebebf286c3e Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 14:02:19 +0200 Subject: [PATCH 133/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index a8a9716a80..0b5d3fdd1d 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1863,8 +1863,8 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - source.f64[1] + source.f64[0], - source.f64[1] + source.f64[0], + destination.f64[1] + source.f64[0], + destination.f64[1] + source.f64[0], ], }; write_xmm_reg128(r, result); From 63423b36f0ee1456c578745aaf211d9f742f95cb Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 14:09:38 +0200 Subject: [PATCH 134/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 0b5d3fdd1d..6c9c7ffbd1 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1863,8 +1863,8 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - destination.f64[1] + source.f64[0], - destination.f64[1] + source.f64[0], + source.f64[0] + destination.f64[1], + source.f64[0] + destination.f64[1], ], }; write_xmm_reg128(r, result); From 7a454cd7fd324a78b0ecc18bb1085e375ece1670 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 14:12:38 +0200 Subject: [PATCH 135/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 6c9c7ffbd1..0e92459d8c 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1862,9 +1862,11 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { // haddpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f64: [ - source.f64[0] + destination.f64[1], - source.f64[0] + destination.f64[1], + f32: [ + destination.f32[0] * destination.f32[1], + destination.f32[2] * destination.f32[3], + source.f32[0] * source.f32[1], + source.f32[2] * source.f32[3], ], }; write_xmm_reg128(r, result); From d054300e00adda4a6c60a5ac240925a38c9be5c6 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 14:29:03 +0200 Subject: [PATCH 136/180] Update lib.rs --- src/rust/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rust/lib.rs b/src/rust/lib.rs index ebd3b89ab6..2ceb1784aa 100644 --- a/src/rust/lib.rs +++ b/src/rust/lib.rs @@ -1,3 +1,4 @@ +#![allow(nonstandard-style)] #![allow(const_item_mutation)] #[macro_use] From 65c8698a6f5518a04e651c36437e7f37817e2319 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 14:36:39 +0200 Subject: [PATCH 137/180] Update lib.rs --- src/rust/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/lib.rs b/src/rust/lib.rs index 2ceb1784aa..8576368fc6 100644 --- a/src/rust/lib.rs +++ b/src/rust/lib.rs @@ -1,4 +1,4 @@ -#![allow(nonstandard-style)] +#![allow(nonstandard-style)], #![allow(const_item_mutation)] #[macro_use] From d277af3195bc08b31de548fdcc8d7e0113231579 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 14:41:43 +0200 Subject: [PATCH 138/180] Update lib.rs --- src/rust/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rust/lib.rs b/src/rust/lib.rs index 8576368fc6..0a86f5f4e1 100644 --- a/src/rust/lib.rs +++ b/src/rust/lib.rs @@ -1,4 +1,5 @@ -#![allow(nonstandard-style)], +#![allow(nonstandard-style)] + #![allow(const_item_mutation)] #[macro_use] From d2f08f89762f968a9db4abab066621b894e84d7f Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 14:43:39 +0200 Subject: [PATCH 139/180] Update lib.rs --- src/rust/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/lib.rs b/src/rust/lib.rs index 0a86f5f4e1..60c915c6fb 100644 --- a/src/rust/lib.rs +++ b/src/rust/lib.rs @@ -1,4 +1,4 @@ -#![allow(nonstandard-style)] +#![allow(nonstandard_style)] #![allow(const_item_mutation)] From dcd4b138b8c6a71d1032daf50e966b7f44ed987e Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 18:47:41 +0200 Subject: [PATCH 140/180] Update instructions.rs --- src/rust/cpu/instructions.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index 509518700b..ca92e45d67 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1671,10 +1671,6 @@ pub unsafe fn instr_DD(source: reg128, r: i32) { }; write_xmm_reg128(r, result); } -pub unsafe fn instr_DD_reg(r1: i32, r2: i32) { instr_DD(read_xmm128s(r1), r2); } -pub unsafe fn instr_DD_mem(addr: i32, r: i32) { - instr_DD(return_on_pagefault!(safe_read128s(addr)), r); -} #[no_mangle] pub unsafe fn instr_D4(arg: i32) { bcd_aam(arg); } #[no_mangle] From 47b1cf664615f8c32e2b2ecc45bd8617bb945db7 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 18:49:02 +0200 Subject: [PATCH 141/180] Update x86_table.js --- gen/x86_table.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gen/x86_table.js b/gen/x86_table.js index ef8f8acdc9..a6fe5de3e0 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -631,8 +631,8 @@ const encodings = [ { sse: 1, opcode: 0xF20F11, e: 1, custom: 1 }, { sse: 1, opcode: 0x0F12, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F12, reg_ud: 1, e: 1, custom: 1 }, - { sse: 1, opcode: 0xF20F12, e: 1, block_boundary: 1, custom: 1 }, // sse3 - { sse: 1, opcode: 0xF30F12, e: 1, block_boundary: 1, custom: 1 }, // sse3 + { sse: 1, opcode: 0xF20F12, e: 1, custom: 1 }, // sse3 + { sse: 1, opcode: 0xF30F12, e: 1, custom: 1 }, // sse3 { sse: 1, opcode: 0x0F13, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F13, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0x0F14, e: 1, custom: 1 }, @@ -641,7 +641,7 @@ const encodings = [ { sse: 1, opcode: 0x660F15, e: 1, custom: 1 }, { sse: 1, opcode: 0x0F16, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F16, reg_ud: 1, e: 1, custom: 1 }, - { sse: 1, opcode: 0xF30F16, e: 1, block_boundary: 1, custom: 1 }, // sse3 + { sse: 1, opcode: 0xF30F16, e: 1, custom: 1 }, // sse3 { sse: 1, opcode: 0x0F17, reg_ud: 1, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F17, reg_ud: 1, e: 1, custom: 1 }, From cd39497307f3ef3374fbd65cfc61f15c2921d9c2 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 18:57:04 +0200 Subject: [PATCH 142/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 0e92459d8c..64e7d35ee5 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -557,8 +557,8 @@ pub unsafe fn instr_F20F12(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - destination.f64[0] + source.f64[0], - destination.f64[1] + source.f64[0], + destination.f64[0] := source.f64[0], + destination.f64[1] := source.f64[0], ], }; write_xmm_reg128(r, result); @@ -1863,10 +1863,10 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f32: [ - destination.f32[0] * destination.f32[1], - destination.f32[2] * destination.f32[3], - source.f32[0] * source.f32[1], - source.f32[2] * source.f32[3], + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], ], }; write_xmm_reg128(r, result); From 8e531f5d08e8dd35786493f8d0a097343a32d5b6 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 18:59:38 +0200 Subject: [PATCH 143/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 64e7d35ee5..cadd1c659c 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -557,8 +557,8 @@ pub unsafe fn instr_F20F12(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - destination.f64[0] := source.f64[0], - destination.f64[1] := source.f64[0], + destination.f64[0] = source.f64[0], + destination.f64[1] = source.f64[0], ], }; write_xmm_reg128(r, result); From 1e443a4ca695201681e06ba4b16855889538b610 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 19:05:04 +0200 Subject: [PATCH 144/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index cadd1c659c..38d88d0604 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -554,14 +554,7 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { #[no_mangle] pub unsafe fn instr_F20F12(source: reg128, r: i32) { // movddup xmm1, xmm2/m64 - let destination = read_xmm128s(r); - let result = reg128 { - f64: [ - destination.f64[0] = source.f64[0], - destination.f64[1] = source.f64[0], - ], - }; - write_xmm_reg128(r, result); + mov_rm_r128(source, r); } pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm128s(r1), r2); } pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { From 63cbca2878a2db06ee6f87593a9c526b661178d3 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 19:18:12 +0200 Subject: [PATCH 145/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 38d88d0604..17612c1ee8 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -554,7 +554,7 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { #[no_mangle] pub unsafe fn instr_F20F12(source: reg128, r: i32) { // movddup xmm1, xmm2/m64 - mov_rm_r128(source, r); + mov_r_r128(r1, r2); } pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm128s(r1), r2); } pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { From c5a52eabf2df6ee0ea41914cf382d80eb07a8b22 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 19:24:06 +0200 Subject: [PATCH 146/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 17612c1ee8..38d88d0604 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -554,7 +554,7 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { #[no_mangle] pub unsafe fn instr_F20F12(source: reg128, r: i32) { // movddup xmm1, xmm2/m64 - mov_r_r128(r1, r2); + mov_rm_r128(source, r); } pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm128s(r1), r2); } pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { From 4163c12f3a66ddc3eddaa2ebec565ed3457f08ad Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 19:27:32 +0200 Subject: [PATCH 147/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 38d88d0604..9ad85c5046 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -554,7 +554,8 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { #[no_mangle] pub unsafe fn instr_F20F12(source: reg128, r: i32) { // movddup xmm1, xmm2/m64 - mov_rm_r128(source, r); + let destination = read_xmm64s(r); + write_xmm_f64(r, f64::from_bits(destination) - f64::from_bits(source)); } pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm128s(r1), r2); } pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { From 72bde3ae61f7e74c5a19d3a4530984feb003f571 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 19:30:38 +0200 Subject: [PATCH 148/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 9ad85c5046..c9e57f64e4 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -552,7 +552,7 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { write_xmm64(r, data); } #[no_mangle] -pub unsafe fn instr_F20F12(source: reg128, r: i32) { +pub unsafe fn instr_F20F12(source: u64, r: i32) { // movddup xmm1, xmm2/m64 let destination = read_xmm64s(r); write_xmm_f64(r, f64::from_bits(destination) - f64::from_bits(source)); From 59b1b66d18545716d3837c79c3ef5c6fd18fae32 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 19:33:22 +0200 Subject: [PATCH 149/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index c9e57f64e4..5fb8fa34f3 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -557,7 +557,7 @@ pub unsafe fn instr_F20F12(source: u64, r: i32) { let destination = read_xmm64s(r); write_xmm_f64(r, f64::from_bits(destination) - f64::from_bits(source)); } -pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm128s(r1), r2); } +pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm64s(r1), r2); } pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { instr_F20F12(return_on_pagefault!(safe_read128s(addr)), r); } From a2a1428552d86764dd1b71b1d845dc58f8deb8d8 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 19:38:19 +0200 Subject: [PATCH 150/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 5fb8fa34f3..cb7b0d2578 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -553,13 +553,13 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { } #[no_mangle] pub unsafe fn instr_F20F12(source: u64, r: i32) { - // movddup xmm1, xmm2/m64 + // movddup xmm, xmm/mem64 let destination = read_xmm64s(r); write_xmm_f64(r, f64::from_bits(destination) - f64::from_bits(source)); } pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm64s(r1), r2); } pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { - instr_F20F12(return_on_pagefault!(safe_read128s(addr)), r); + instr_F20F12(return_on_pagefault!(safe_read64s(addr)), r); } #[no_mangle] pub unsafe fn instr_F30F12(source: reg128, r: i32) { From 6f9d83443f87d11c4dbd338408d9f43d8b77ce54 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 20:01:18 +0200 Subject: [PATCH 151/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index cb7b0d2578..0b383d56c6 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -562,22 +562,15 @@ pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { instr_F20F12(return_on_pagefault!(safe_read64s(addr)), r); } #[no_mangle] -pub unsafe fn instr_F30F12(source: reg128, r: i32) { +pub unsafe fn instr_F30F12(source: f32, r: i32) { // movsldup xmm1, xmm2/m128 - let destination = read_xmm128s(r); - let result = reg128 { - f32: [ - destination.f32[0] + source.f32[0], - destination.f32[1] + source.f32[0], - destination.f32[2] + source.f32[2], - destination.f32[3] + source.f32[2], - ], - }; - write_xmm_reg128(r, result); + let destination = read_xmm_f32(r); + let result = destination - source; + write_xmm_f32(r, result); } -pub unsafe fn instr_F30F12_reg(r1: i32, r2: i32) { instr_F30F12(read_xmm128s(r1), r2); } +pub unsafe fn instr_F30F12_reg(r1: i32, r2: i32) { instr_F30F12(read_xmm_f32(r1), r2); } pub unsafe fn instr_F30F12_mem(addr: i32, r: i32) { - instr_F30F12(return_on_pagefault!(safe_read128s(addr)), r); + instr_F30F12(return_on_pagefault!(safe_read_f32(addr)), r); } pub unsafe fn instr_0F13_mem(addr: i32, r: i32) { // movlps m64, xmm From 59586b75be6cd24fc93cc745258602ed409bdc45 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Thu, 14 Sep 2023 20:03:07 +0200 Subject: [PATCH 152/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 0b383d56c6..90a8165898 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -668,22 +668,15 @@ pub unsafe fn instr_660F16_mem(addr: i32, r: i32) { } pub unsafe fn instr_660F16_reg(_r1: i32, _r2: i32) { trigger_ud(); } #[no_mangle] -pub unsafe fn instr_F30F16(source: reg128, r: i32) { +pub unsafe fn instr_F30F16(source: f32, r: i32) { // movshdup xmm1, xmm2/m128 - let destination = read_xmm128s(r); - let result = reg128 { - f32: [ - destination.f32[0] + source.f32[1], - destination.f32[1] + source.f32[1], - destination.f32[2] + source.f32[3], - destination.f32[3] + source.f32[3], - ], - }; - write_xmm_reg128(r, result); + let destination = read_xmm_f32(r); + let result = destination - source; + write_xmm_f32(r, result); } -pub unsafe fn instr_F30F16_reg(r1: i32, r2: i32) { instr_F30F16(read_xmm128s(r1), r2); } +pub unsafe fn instr_F30F16_reg(r1: i32, r2: i32) { instr_F30F16(read_xmm_f32(r1), r2); } pub unsafe fn instr_F30F16_mem(addr: i32, r: i32) { - instr_F30F16(return_on_pagefault!(safe_read128s(addr)), r); + instr_F30F16(return_on_pagefault!(safe_read_f32(addr)), r); } pub unsafe fn instr_0F17_mem(addr: i32, r: i32) { // movhps m64, xmm From 0546588ed4747919de9ae917df9dd747f6537e68 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 08:34:09 +0200 Subject: [PATCH 153/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 90a8165898..d40155e269 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1842,11 +1842,9 @@ pub unsafe fn instr_660F7C(source: reg128, r: i32) { // haddpd xmm1, xmm2/m128 let destination = read_xmm128s(r); let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], + f64: [ + destination.f64[0] + destination.f64[1], + source.f64[0] + source.f64[1], ], }; write_xmm_reg128(r, result); From 40a72cac8fdbbc057621afdaaa37edb9f4fbf3c5 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 08:48:57 +0200 Subject: [PATCH 154/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index d40155e269..5a8988a20d 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1859,8 +1859,8 @@ pub unsafe fn instr_660F7D(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f64: [ - source.f64[0] - destination.f64[1], - source.f64[0] - destination.f64[1], + destination.f64[0] - destination.f64[1], + source.f64[0] - source.f64[1], ], }; write_xmm_reg128(r, result); From 1ce6002bf777e2ac4a40097cb9cd8b8ca6ef0fc3 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 09:02:38 +0200 Subject: [PATCH 155/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 5a8988a20d..b81c295b68 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -552,14 +552,13 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { write_xmm64(r, data); } #[no_mangle] -pub unsafe fn instr_F20F12(source: u64, r: i32) { +pub unsafe fn instr_F20F12(source: reg128, r: i32) { // movddup xmm, xmm/mem64 - let destination = read_xmm64s(r); - write_xmm_f64(r, f64::from_bits(destination) - f64::from_bits(source)); + mov_rm_r128(source, r); } -pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm64s(r1), r2); } +pub unsafe fn instr_F2F012_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm128s(r1), r2); } pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { - instr_F20F12(return_on_pagefault!(safe_read64s(addr)), r); + instr_F20F12(return_on_pagefault!(safe_read128s(addr)), r); } #[no_mangle] pub unsafe fn instr_F30F12(source: f32, r: i32) { From 4f0a7978d51539ca220ea0acc5da3407db7b8073 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 09:04:56 +0200 Subject: [PATCH 156/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index b81c295b68..b512422b57 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -556,7 +556,7 @@ pub unsafe fn instr_F20F12(source: reg128, r: i32) { // movddup xmm, xmm/mem64 mov_rm_r128(source, r); } -pub unsafe fn instr_F2F012_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm128s(r1), r2); } +pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm128s(r1), r2); } pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { instr_F20F12(return_on_pagefault!(safe_read128s(addr)), r); } From 2bb13ac98dc486fc7bcea5c57b581ef94c3340a1 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 09:41:21 +0200 Subject: [PATCH 157/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index b512422b57..e053ea34bf 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -554,7 +554,7 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { #[no_mangle] pub unsafe fn instr_F20F12(source: reg128, r: i32) { // movddup xmm, xmm/mem64 - mov_rm_r128(source, r); + mov_r_m128(addr, r); } pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm128s(r1), r2); } pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { From f442d087523ba6004c7ca12cfcfef4e4740dcb6e Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 09:47:34 +0200 Subject: [PATCH 158/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index e053ea34bf..9b6b900030 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -552,7 +552,7 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { write_xmm64(r, data); } #[no_mangle] -pub unsafe fn instr_F20F12(source: reg128, r: i32) { +pub unsafe fn instr_F20F12(addr: i32, r: i32) { // movddup xmm, xmm/mem64 mov_r_m128(addr, r); } From b6cf834ee239b447cee2e081df454e6eb7a78a8b Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 09:51:29 +0200 Subject: [PATCH 159/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 9b6b900030..77f324af06 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -556,8 +556,8 @@ pub unsafe fn instr_F20F12(addr: i32, r: i32) { // movddup xmm, xmm/mem64 mov_r_m128(addr, r); } -pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm128s(r1), r2); } -pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { +pub unsafe fn instr_F20F12_reg(_r1: i32, _r2: i32) { trigger_ud(); } +pub unsafe fn instr_F20F12_mem(_r1: i32, _r2: i32) { instr_F20F12(return_on_pagefault!(safe_read128s(addr)), r); } #[no_mangle] From d7ef854d3159d9f77dca05ca5d553e4db0909e30 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 09:54:58 +0200 Subject: [PATCH 160/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 77f324af06..87a0847a29 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -552,14 +552,11 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { write_xmm64(r, data); } #[no_mangle] -pub unsafe fn instr_F20F12(addr: i32, r: i32) { +pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { // movddup xmm, xmm/mem64 - mov_r_m128(addr, r); -} -pub unsafe fn instr_F20F12_reg(_r1: i32, _r2: i32) { trigger_ud(); } -pub unsafe fn instr_F20F12_mem(_r1: i32, _r2: i32) { - instr_F20F12(return_on_pagefault!(safe_read128s(addr)), r); + movl_r128_m64(addr, r); } +pub unsafe fn instr_F20F12_reg(_r1: i32, _r2: i32) { trigger_ud(); #[no_mangle] pub unsafe fn instr_F30F12(source: f32, r: i32) { // movsldup xmm1, xmm2/m128 From cf5629f6bae7832f3d54c63c9edce1b69b6de80e Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 09:57:19 +0200 Subject: [PATCH 161/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 87a0847a29..c0963b7bf5 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -556,7 +556,7 @@ pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { // movddup xmm, xmm/mem64 movl_r128_m64(addr, r); } -pub unsafe fn instr_F20F12_reg(_r1: i32, _r2: i32) { trigger_ud(); +pub unsafe fn instr_F20F12_reg(_r1: i32, _r2: i32) { trigger_ud(); } #[no_mangle] pub unsafe fn instr_F30F12(source: f32, r: i32) { // movsldup xmm1, xmm2/m128 From d76a05b36ac8574e911266d3d81f22d0bdbc7b74 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 10:14:23 +0200 Subject: [PATCH 162/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index c0963b7bf5..d05571b735 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -552,11 +552,14 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { write_xmm64(r, data); } #[no_mangle] +pub unsafe fn instr_F20F12(source: i32, r: i32) { + // movddup xmm1, xmm2/m64 + write_xmm128(r, source, 0, 0, 0); +} +pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_reg32(r1), r2); } pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { - // movddup xmm, xmm/mem64 - movl_r128_m64(addr, r); + instr_F20F12(return_on_pagefault!(safe_read32s(addr)), r); } -pub unsafe fn instr_F20F12_reg(_r1: i32, _r2: i32) { trigger_ud(); } #[no_mangle] pub unsafe fn instr_F30F12(source: f32, r: i32) { // movsldup xmm1, xmm2/m128 From df169275083583fa4b9f86418902fac23387a7af Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 14:48:08 +0200 Subject: [PATCH 163/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index d05571b735..e4691b3b74 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -552,12 +552,12 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { write_xmm64(r, data); } #[no_mangle] -pub unsafe fn instr_F20F12(source: i32, r: i32) { +pub unsafe fn instr_F20F12(source: reg128, r: i32) { // movddup xmm1, xmm2/m64 - write_xmm128(r, source, 0, 0, 0); + movh_r128_m64(addr, r); } -pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_reg32(r1), r2); } -pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { +pub unsafe fn instr_F20F12_reg(r1: reg128, r2: i32) { instr_F20F12(read_reg32(r1), r2); } +pub unsafe fn instr_F20F12_mem(addr: reg128, r: i32) { instr_F20F12(return_on_pagefault!(safe_read32s(addr)), r); } #[no_mangle] @@ -3193,7 +3193,7 @@ pub unsafe fn instr_0FA2() { let mut ebx = 0; let level = read_reg32(EAX) as u32; - + match level { 0 => { // maximum supported level (default 0x16, overwritten to 2 as a workaround for Windows NT) From b03640e7f95f87da2d0aaf3246283eda5c3a315a Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 14:54:14 +0200 Subject: [PATCH 164/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index e4691b3b74..08d8357ec7 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -556,7 +556,7 @@ pub unsafe fn instr_F20F12(source: reg128, r: i32) { // movddup xmm1, xmm2/m64 movh_r128_m64(addr, r); } -pub unsafe fn instr_F20F12_reg(r1: reg128, r2: i32) { instr_F20F12(read_reg32(r1), r2); } +pub unsafe fn instr_F20F12_reg(r1: reg128, r2: i32) { instr_F20F12(read_reg128(r1), r2); } pub unsafe fn instr_F20F12_mem(addr: reg128, r: i32) { instr_F20F12(return_on_pagefault!(safe_read32s(addr)), r); } From f868ecc0374842212310d5660bce2dbb5fadc593 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 14:56:37 +0200 Subject: [PATCH 165/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 08d8357ec7..525c6ed03e 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -556,9 +556,9 @@ pub unsafe fn instr_F20F12(source: reg128, r: i32) { // movddup xmm1, xmm2/m64 movh_r128_m64(addr, r); } -pub unsafe fn instr_F20F12_reg(r1: reg128, r2: i32) { instr_F20F12(read_reg128(r1), r2); } -pub unsafe fn instr_F20F12_mem(addr: reg128, r: i32) { - instr_F20F12(return_on_pagefault!(safe_read32s(addr)), r); +pub unsafe fn instr_F20F12_reg(r1: i32, r: i32) { instr_F20F12(read_xmm64s(r1), r); } +pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { + instr_F2F012(return_on_pagefault!(safe_read64s(addr)), r) } #[no_mangle] pub unsafe fn instr_F30F12(source: f32, r: i32) { From ab53f26d3d5d8e9d4cbffc558bcc08270ea685aa Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 15:02:27 +0200 Subject: [PATCH 166/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 525c6ed03e..828a44ff40 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -552,13 +552,13 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { write_xmm64(r, data); } #[no_mangle] -pub unsafe fn instr_F20F12(source: reg128, r: i32) { +pub unsafe fn instr_F20F12(source: f32, r: i32) { // movddup xmm1, xmm2/m64 movh_r128_m64(addr, r); } pub unsafe fn instr_F20F12_reg(r1: i32, r: i32) { instr_F20F12(read_xmm64s(r1), r); } pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { - instr_F2F012(return_on_pagefault!(safe_read64s(addr)), r) + instr_F20F12(return_on_pagefault!(safe_read64s(addr)), r) } #[no_mangle] pub unsafe fn instr_F30F12(source: f32, r: i32) { From c1cb511083b1d801f4bb7c590e0319640c2a6725 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 15:15:56 +0200 Subject: [PATCH 167/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 828a44ff40..2a10c552b3 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -554,18 +554,23 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { #[no_mangle] pub unsafe fn instr_F20F12(source: f32, r: i32) { // movddup xmm1, xmm2/m64 - movh_r128_m64(addr, r); + let destination = read_xmm_f32(r); + let result = destination - source; + write_xmm_f32(r, result); } -pub unsafe fn instr_F20F12_reg(r1: i32, r: i32) { instr_F20F12(read_xmm64s(r1), r); } +pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm_f32(r1), r2); } pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { - instr_F20F12(return_on_pagefault!(safe_read64s(addr)), r) + instr_F20F12(return_on_pagefault!(safe_read64s(addr)), r); } #[no_mangle] -pub unsafe fn instr_F30F12(source: f32, r: i32) { +pub unsafe fn instr_F30F12(source: reg128, r: i32) { // movsldup xmm1, xmm2/m128 - let destination = read_xmm_f32(r); - let result = destination - source; - write_xmm_f32(r, result); + let destination = read_xmm128s(r); + let mut result = reg128 { i8: [0; 16] }; + for i in 0..8 { + result.i16[i] = i16::max(destination.i16[i], source.i16[i]) + } + write_xmm_reg128(r, result); } pub unsafe fn instr_F30F12_reg(r1: i32, r2: i32) { instr_F30F12(read_xmm_f32(r1), r2); } pub unsafe fn instr_F30F12_mem(addr: i32, r: i32) { From a869575f31a86d2623b845e8b3c0daf1d79eeadd Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 15:32:02 +0200 Subject: [PATCH 168/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 2a10c552b3..623169e1e5 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -560,7 +560,7 @@ pub unsafe fn instr_F20F12(source: f32, r: i32) { } pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm_f32(r1), r2); } pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { - instr_F20F12(return_on_pagefault!(safe_read64s(addr)), r); + instr_F20F12(return_on_pagefault!(safe_read_f32(addr)), r); } #[no_mangle] pub unsafe fn instr_F30F12(source: reg128, r: i32) { @@ -572,9 +572,9 @@ pub unsafe fn instr_F30F12(source: reg128, r: i32) { } write_xmm_reg128(r, result); } -pub unsafe fn instr_F30F12_reg(r1: i32, r2: i32) { instr_F30F12(read_xmm_f32(r1), r2); } +pub unsafe fn instr_F30F12_reg(r1: i32, r2: i32) { instr_F30F12(read_xmm128s(r1), r2); } pub unsafe fn instr_F30F12_mem(addr: i32, r: i32) { - instr_F30F12(return_on_pagefault!(safe_read_f32(addr)), r); + instr_F30F12(return_on_pagefault!(safe_read128s(addr)), r); } pub unsafe fn instr_0F13_mem(addr: i32, r: i32) { // movlps m64, xmm From 90efc9f5eeea7cce05391f9ae5b472cd0c9622eb Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 16:08:17 +0200 Subject: [PATCH 169/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 623169e1e5..d909e55dac 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -555,8 +555,7 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { pub unsafe fn instr_F20F12(source: f32, r: i32) { // movddup xmm1, xmm2/m64 let destination = read_xmm_f32(r); - let result = destination - source; - write_xmm_f32(r, result); + write_xmm_f32(r, f64::from_bits(source), f64::from_bits(source)); } pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm_f32(r1), r2); } pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { @@ -2045,7 +2044,7 @@ pub unsafe fn instr_660F5C_mem(addr: i32, r: i32) { } #[no_mangle] pub unsafe fn instr_F20F5C(source: u64, r: i32) { - // subsd xmm, xmm/mem64 + // subsd xmm1, xmm2/m64 let destination = read_xmm64s(r); write_xmm_f64(r, f64::from_bits(destination) - f64::from_bits(source)); } From f8bf9b8e647ca89765016b1d5706d5d7969cfe3b Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 16:10:50 +0200 Subject: [PATCH 170/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index d909e55dac..c885586913 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -552,7 +552,7 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { write_xmm64(r, data); } #[no_mangle] -pub unsafe fn instr_F20F12(source: f32, r: i32) { +pub unsafe fn instr_F20F12(source: u64, r: i32) { // movddup xmm1, xmm2/m64 let destination = read_xmm_f32(r); write_xmm_f32(r, f64::from_bits(source), f64::from_bits(source)); From 1da2d1fbc7c737ee0ac4751ad3e52312fb5a0e60 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 18:34:57 +0200 Subject: [PATCH 171/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index c885586913..3a41e84cdc 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -552,14 +552,20 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { write_xmm64(r, data); } #[no_mangle] -pub unsafe fn instr_F20F12(source: u64, r: i32) { - // movddup xmm1, xmm2/m64 - let destination = read_xmm_f32(r); - write_xmm_f32(r, f64::from_bits(source), f64::from_bits(source)); +pub unsafe fn instr_F20F12(source: reg128, r: i32) { + // haddps xmm, xmm/mem128 + let destination = read_xmm128s(r); + let result = reg128 { + f64: [ + destination.f64[0] + source.f64[1], + destination.f64[2] + source.f64[3], + ], + }; + write_xmm_reg128(r, result); } -pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm_f32(r1), r2); } +pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm128s(r1), r2); } pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { - instr_F20F12(return_on_pagefault!(safe_read_f32(addr)), r); + instr_F20F12(return_on_pagefault!(safe_read128s(addr)), r); } #[no_mangle] pub unsafe fn instr_F30F12(source: reg128, r: i32) { From 2c3798a50673f4e9e7161e4468cc57aa576a2921 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 18:35:12 +0200 Subject: [PATCH 172/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 3a41e84cdc..0034754680 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -553,7 +553,7 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { } #[no_mangle] pub unsafe fn instr_F20F12(source: reg128, r: i32) { - // haddps xmm, xmm/mem128 + // movsldup xmm, xmm/mem128 let destination = read_xmm128s(r); let result = reg128 { f64: [ From b3479616b50613e7fe7bd5be406be9d26fe26d7a Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 18:36:05 +0200 Subject: [PATCH 173/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 0034754680..c43ccd2898 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -553,7 +553,7 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { } #[no_mangle] pub unsafe fn instr_F20F12(source: reg128, r: i32) { - // movsldup xmm, xmm/mem128 + // movddup xmm, xmm/mem128 let destination = read_xmm128s(r); let result = reg128 { f64: [ From a45b953756181f2c29fbd34ef5c78733ee9d0c4f Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 20:05:06 +0200 Subject: [PATCH 174/180] Update instructions_0f.rs if this aint working then idk lmao --- src/rust/cpu/instructions_0f.rs | 38 +++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index c43ccd2898..d6d75e8a67 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -552,18 +552,18 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { write_xmm64(r, data); } #[no_mangle] -pub unsafe fn instr_F20F12(source: reg128, r: i32) { - // movddup xmm, xmm/mem128 - let destination = read_xmm128s(r); - let result = reg128 { +pub unsafe fn instr_F20F12(source: u64, r: i32) { + // movddup xmm, xmm/mem64 + let destination = read_xmm64s(r); + let result = reg64 { f64: [ - destination.f64[0] + source.f64[1], - destination.f64[2] + source.f64[3], + destination.f64[0] = source.f64[0], + destination.f64[1] = source.f64[0], ], }; write_xmm_reg128(r, result); } -pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm128s(r1), r2); } +pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm64s(r1), r2); } pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { instr_F20F12(return_on_pagefault!(safe_read128s(addr)), r); } @@ -571,9 +571,13 @@ pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { pub unsafe fn instr_F30F12(source: reg128, r: i32) { // movsldup xmm1, xmm2/m128 let destination = read_xmm128s(r); - let mut result = reg128 { i8: [0; 16] }; - for i in 0..8 { - result.i16[i] = i16::max(destination.i16[i], source.i16[i]) + let result = reg128 { + f32: [ + destination.f32[0] = source.f32[0]; + destination.f32[1] = source.f32[0]; + destination.f32[2] = source.f32[2]; + destination.f32[3] = source.f32[2]; + ] } write_xmm_reg128(r, result); } @@ -677,13 +681,19 @@ pub unsafe fn instr_660F16_mem(addr: i32, r: i32) { } pub unsafe fn instr_660F16_reg(_r1: i32, _r2: i32) { trigger_ud(); } #[no_mangle] -pub unsafe fn instr_F30F16(source: f32, r: i32) { +pub unsafe fn instr_F30F16(source: reg128, r: i32) { // movshdup xmm1, xmm2/m128 let destination = read_xmm_f32(r); - let result = destination - source; - write_xmm_f32(r, result); + let result = reg128 { + f32: [ + destination.f32[0] = source.f32[1]; + destination.f32[1] = source.f32[1]; + destination.f32[2] = source.f32[3]; + destination.f32[3] = source.f32[3]; + ] + } } -pub unsafe fn instr_F30F16_reg(r1: i32, r2: i32) { instr_F30F16(read_xmm_f32(r1), r2); } +pub unsafe fn instr_F30F16_reg(r1: i32, r2: i32) { instr_F30F16(read_xmm128s(r1), r2); } pub unsafe fn instr_F30F16_mem(addr: i32, r: i32) { instr_F30F16(return_on_pagefault!(safe_read_f32(addr)), r); } From 463aa88efc0da22f0401d61e289d2556023065cd Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 20:09:16 +0200 Subject: [PATCH 175/180] Update instructions_0f.rs .. --- src/rust/cpu/instructions_0f.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index d6d75e8a67..2a68e70924 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -686,7 +686,7 @@ pub unsafe fn instr_F30F16(source: reg128, r: i32) { let destination = read_xmm_f32(r); let result = reg128 { f32: [ - destination.f32[0] = source.f32[1]; + destination.f32[0] = source.f32[1]; destination.f32[1] = source.f32[1]; destination.f32[2] = source.f32[3]; destination.f32[3] = source.f32[3]; @@ -695,7 +695,7 @@ pub unsafe fn instr_F30F16(source: reg128, r: i32) { } pub unsafe fn instr_F30F16_reg(r1: i32, r2: i32) { instr_F30F16(read_xmm128s(r1), r2); } pub unsafe fn instr_F30F16_mem(addr: i32, r: i32) { - instr_F30F16(return_on_pagefault!(safe_read_f32(addr)), r); + instr_F30F16(return_on_pagefault!(safe_read128s(addr)), r); } pub unsafe fn instr_0F17_mem(addr: i32, r: i32) { // movhps m64, xmm From 5d2b9f5a3349fe6981d66a3260b2bf6185ae6caf Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 20:25:13 +0200 Subject: [PATCH 176/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 2a68e70924..f53983e34c 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -552,10 +552,10 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { write_xmm64(r, data); } #[no_mangle] -pub unsafe fn instr_F20F12(source: u64, r: i32) { - // movddup xmm, xmm/mem64 +pub unsafe fn instr_F20F12(source: reg128, r: i32) { + // movddup xmm1, xmm2/m64 let destination = read_xmm64s(r); - let result = reg64 { + let result = reg128 { f64: [ destination.f64[0] = source.f64[0], destination.f64[1] = source.f64[0], @@ -573,12 +573,12 @@ pub unsafe fn instr_F30F12(source: reg128, r: i32) { let destination = read_xmm128s(r); let result = reg128 { f32: [ - destination.f32[0] = source.f32[0]; - destination.f32[1] = source.f32[0]; - destination.f32[2] = source.f32[2]; - destination.f32[3] = source.f32[2]; - ] - } + destination.f32[0] = source.f32[0], + destination.f32[1] = source.f32[0], + destination.f32[2] = source.f32[2], + destination.f32[3] = source.f32[2], + ], + }; write_xmm_reg128(r, result); } pub unsafe fn instr_F30F12_reg(r1: i32, r2: i32) { instr_F30F12(read_xmm128s(r1), r2); } @@ -686,9 +686,9 @@ pub unsafe fn instr_F30F16(source: reg128, r: i32) { let destination = read_xmm_f32(r); let result = reg128 { f32: [ - destination.f32[0] = source.f32[1]; - destination.f32[1] = source.f32[1]; - destination.f32[2] = source.f32[3]; + destination.f32[0] = source.f32[1]; + destination.f32[1] = source.f32[1]; + destination.f32[2] = source.f32[3]; destination.f32[3] = source.f32[3]; ] } From 860ef95358428cc802c50a0fad223c6f13117048 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 20:31:59 +0200 Subject: [PATCH 177/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index f53983e34c..efc5a9d2bf 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -686,12 +686,12 @@ pub unsafe fn instr_F30F16(source: reg128, r: i32) { let destination = read_xmm_f32(r); let result = reg128 { f32: [ - destination.f32[0] = source.f32[1]; - destination.f32[1] = source.f32[1]; - destination.f32[2] = source.f32[3]; - destination.f32[3] = source.f32[3]; + destination.f32[0] = source.f32[1], + destination.f32[1] = source.f32[1], + destination.f32[2] = source.f32[3], + destination.f32[3] = source.f32[3], ] - } + }; } pub unsafe fn instr_F30F16_reg(r1: i32, r2: i32) { instr_F30F16(read_xmm128s(r1), r2); } pub unsafe fn instr_F30F16_mem(addr: i32, r: i32) { From 5653e4817cfa545074cdb590845b10a181ec536b Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 20:39:10 +0200 Subject: [PATCH 178/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index efc5a9d2bf..e6d2beb3cc 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -563,7 +563,7 @@ pub unsafe fn instr_F20F12(source: reg128, r: i32) { }; write_xmm_reg128(r, result); } -pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm64s(r1), r2); } +pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm128s(r1), r2); } pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { instr_F20F12(return_on_pagefault!(safe_read128s(addr)), r); } From 1ec9248eb3a46ed8fbe761ddab144e76c6284381 Mon Sep 17 00:00:00 2001 From: Ryan <69303239+spetterman66@users.noreply.github.com> Date: Fri, 15 Sep 2023 20:54:22 +0200 Subject: [PATCH 179/180] Update instructions_0f.rs --- src/rust/cpu/instructions_0f.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index e6d2beb3cc..55405d208a 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -554,7 +554,7 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { #[no_mangle] pub unsafe fn instr_F20F12(source: reg128, r: i32) { // movddup xmm1, xmm2/m64 - let destination = read_xmm64s(r); + let destination = read_xmm128s(r); let result = reg128 { f64: [ destination.f64[0] = source.f64[0], From 1a3813703d9567dba9ccec1cc18aa293364f8314 Mon Sep 17 00:00:00 2001 From: Fabian Date: Fri, 15 Sep 2023 17:21:14 -0500 Subject: [PATCH 180/180] fix --- Readme.md | 4 +- gen/x86_table.js | 26 ++--- src/rust/cpu/fpu.rs | 43 +++++-- src/rust/cpu/instructions.rs | 33 +----- src/rust/cpu/instructions_0f.rs | 193 ++++++++++++++++---------------- src/rust/jit_instructions.rs | 102 ++++++++--------- src/rust/lib.rs | 2 - src/rust/softfloat.rs | 3 + 8 files changed, 194 insertions(+), 212 deletions(-) diff --git a/Readme.md b/Readme.md index 0a33a4e213..2308386c8c 100644 --- a/Readme.md +++ b/Readme.md @@ -25,7 +25,7 @@ list of emulated hardware: - A generic VGA card with SVGA support and Bochs VBE Extensions. - A PCI bus. This one is partly incomplete and not used by every device. - An IDE disk controller. -- An NE2000 (AKA RTL8390) PCI network card. +- An NE2000 (RTL8390) PCI network card. - A virtio filesystem. - A SoundBlaster 16 sound card. @@ -81,7 +81,7 @@ Here's an overview of the operating systems supported in v86: - FreeDOS, Windows 1.01 and MS-DOS run very well. - KolibriOS works. - Haiku works. -- Android-x86 works up to 4.4-r2. Newer versions halt on a kernel panic error. +- Android-x86 works up to 4.4-r2, if you select VESA mode at the boot prompt. - Windows 1, 3.x, 95, 98, ME, NT and 2000 work reasonably well. - In Windows 2000 and higher the PC type has to be changed from ACPI PC to Standard PC - There are some known boot issues ([#250](https://github.com/copy/v86/issues/250), [#433](https://github.com/copy/v86/issues/433), [#507](https://github.com/copy/v86/issues/507), [#555](https://github.com/copy/v86/issues/555), [#620](https://github.com/copy/v86/issues/620), [#645](https://github.com/copy/v86/issues/645)) diff --git a/gen/x86_table.js b/gen/x86_table.js index a6fe5de3e0..790b8a2d77 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -341,14 +341,14 @@ const encodings = [ { opcode: 0xDE, e: 1, fixed_g: 6, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDE, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDF, e: 1, fixed_g: 0, custom: 0, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDF, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, }, // fisttp (sse3) - { opcode: 0xDF, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDF, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, }, + { opcode: 0xDF, e: 1, fixed_g: 0, custom: 0, is_fpu: 1, task_switch_test: 1 }, + { opcode: 0xDF, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1 }, // fisttp (sse3) + { opcode: 0xDF, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1 }, + { opcode: 0xDF, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1 }, { opcode: 0xDF, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, skip_mem: 1 }, // unimplemented: Binary Coded Decimals - { opcode: 0xDF, e: 1, fixed_g: 5, custom: 1, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDF, e: 1, fixed_g: 6, custom: 1, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDF, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, }, + { opcode: 0xDF, e: 1, fixed_g: 5, custom: 1, is_fpu: 1, task_switch_test: 1 }, + { opcode: 0xDF, e: 1, fixed_g: 6, custom: 1, is_fpu: 1, task_switch_test: 1 }, + { opcode: 0xDF, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1 }, // loop, jcxz, etc. { opcode: 0xE0, os: 1, imm8s: 1, no_block_boundary_in_interpreted: 1, skip: 1, block_boundary: 1, jump_offset_imm: 1, custom: 1, conditional_jump: 1, }, @@ -477,7 +477,7 @@ const encodings = [ { opcode: 0x0F36, skip: 1, block_boundary: 1, }, // ud { opcode: 0x0F37, skip: 1, block_boundary: 1, }, // getsec - // sse3+ + // ssse3+ { opcode: 0x0F38, skip: 1, block_boundary: 1, }, { opcode: 0x0F39, skip: 1, block_boundary: 1, }, { opcode: 0x0F3A, skip: 1, block_boundary: 1, }, @@ -616,15 +616,12 @@ const encodings = [ // mmx, sse - // - skipped or missing are sse3+ + // - skipped or missing are ssse3+ { sse: 1, opcode: 0x0F10, e: 1, custom: 1 }, { sse: 1, opcode: 0xF30F10, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F10, e: 1, custom: 1 }, - { sse: 1, opcode: 0x660F7C, e: 1, custom: 1 }, // sse3 - { sse: 1, opcode: 0x660F7D, e: 1, custom: 1 }, // sse3 { sse: 1, opcode: 0xF20F10, e: 1, custom: 1 }, - { sse: 1, opcode: 0xF20F7D, e: 1, custom: 1 }, // sse3 { sse: 1, opcode: 0x0F11, e: 1, custom: 1 }, { sse: 1, opcode: 0xF30F11, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F11, e: 1, custom: 1 }, @@ -702,7 +699,10 @@ const encodings = [ { sse: 1, opcode: 0x660F59, e: 1, custom: 1 }, { sse: 1, opcode: 0xF20F59, e: 1, custom: 1 }, { sse: 1, opcode: 0xF30F59, e: 1, custom: 1 }, - { sse: 1, opcode: 0xF20F7C, e: 1, custom: 1 }, + { sse: 1, opcode: 0x660F7C, e: 1, custom: 1 }, // sse3 + { sse: 1, opcode: 0xF20F7C, e: 1, custom: 1 }, // sse3 + { sse: 1, opcode: 0x660F7D, e: 1, custom: 1 }, // sse3 + { sse: 1, opcode: 0xF20F7D, e: 1, custom: 1 }, // sse3 { sse: 1, opcode: 0x0F5A, e: 1, custom: 1 }, { sse: 1, opcode: 0x660F5A, e: 1, custom: 1 }, diff --git a/src/rust/cpu/fpu.rs b/src/rust/cpu/fpu.rs index da8aeb56b2..617a540b78 100644 --- a/src/rust/cpu/fpu.rs +++ b/src/rust/cpu/fpu.rs @@ -326,16 +326,26 @@ pub unsafe fn fpu_fistm16(addr: i32) { safe_write16(addr, v as i32).unwrap(); } #[no_mangle] -pub unsafe fn fpu_fisttpm16(addr: i32) { +pub unsafe fn fpu_fistm16p(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 2)); - let v = fpu_convert_to_i32(fpu_get_st0()); + let v = fpu_convert_to_i16(fpu_get_st0()); safe_write16(addr, v as i32).unwrap(); fpu_pop(); } #[no_mangle] -pub unsafe fn fpu_fistm16p(addr: i32) { +pub unsafe fn fpu_truncate_to_i16(f: F80) -> i16 { + let st0 = fpu_truncate_to_i32(f); + if st0 < -0x8000 || st0 > 0x7FFF { + fpu_invalid_arithmetic(); + -0x8000 + } + else { + st0 as i16 + } +} +pub unsafe fn fpu_fisttpm16(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 2)); - let v = fpu_convert_to_i16(fpu_get_st0()); + let v = fpu_truncate_to_i16(fpu_get_st0()); safe_write16(addr, v as i32).unwrap(); fpu_pop(); } @@ -348,22 +358,28 @@ pub unsafe fn fpu_convert_to_i32(f: F80) -> i32 { x } #[no_mangle] -pub unsafe fn fpu_fisttpm32(addr: i32) { +pub unsafe fn fpu_fistm32(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 4)); let v = fpu_convert_to_i32(fpu_get_st0()); safe_write32(addr, v).unwrap(); - fpu_pop(); } #[no_mangle] -pub unsafe fn fpu_fistm32(addr: i32) { +pub unsafe fn fpu_fistm32p(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 4)); let v = fpu_convert_to_i32(fpu_get_st0()); safe_write32(addr, v).unwrap(); + fpu_pop(); } #[no_mangle] -pub unsafe fn fpu_fistm32p(addr: i32) { +pub unsafe fn fpu_truncate_to_i32(f: F80) -> i32 { + F80::clear_exception_flags(); + let x = f.truncate_to_i32(); + *fpu_status_word |= F80::get_exception_flags() as u16; + x +} +pub unsafe fn fpu_fisttpm32(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 4)); - let v = fpu_convert_to_i32(fpu_get_st0()); + let v = fpu_truncate_to_i32(fpu_get_st0()); safe_write32(addr, v).unwrap(); fpu_pop(); } @@ -383,12 +399,19 @@ pub unsafe fn fpu_fistm64p(addr: i32) { fpu_pop(); } #[no_mangle] +pub unsafe fn fpu_truncate_to_i64(f: F80) -> i64 { + F80::clear_exception_flags(); + let x = f.truncate_to_i64(); + *fpu_status_word |= F80::get_exception_flags() as u16; + x +} pub unsafe fn fpu_fisttpm64(addr: i32) { return_on_pagefault!(writable_or_pagefault(addr, 8)); - let v = fpu_convert_to_i32(fpu_get_st0()); + let v = fpu_truncate_to_i64(fpu_get_st0()); safe_write64(addr, v as u64).unwrap(); fpu_pop(); } + #[no_mangle] pub unsafe fn fpu_fldcw(addr: i32) { let word = return_on_pagefault!(safe_read16(addr)) as u16; diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index ca92e45d67..026f68f0ad 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1639,38 +1639,7 @@ pub unsafe fn instr32_D3_7_mem(addr: i32) { pub unsafe fn instr32_D3_7_reg(r1: i32) { write_reg32(r1, sar32(read_reg32(r1), read_reg8(CL) & 31)); } -#[no_mangle] -pub unsafe fn instr_DF(source: reg128, r: i32) { - // haddps xmm, xmm/mem128 - let destination = read_xmm128s(r); - let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], - ], - }; - write_xmm_reg128(r, result); -} -pub unsafe fn instr_DF_reg(r1: i32, r2: i32) { instr_DF(read_xmm128s(r1), r2); } -pub unsafe fn instr_DF_mem(addr: i32, r: i32) { - instr_DF(return_on_pagefault!(safe_read128s(addr)), r); -} -#[no_mangle] -pub unsafe fn instr_DD(source: reg128, r: i32) { - // haddps xmm, xmm/mem128 - let destination = read_xmm128s(r); - let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], - ], - }; - write_xmm_reg128(r, result); -} + #[no_mangle] pub unsafe fn instr_D4(arg: i32) { bcd_aam(arg); } #[no_mangle] diff --git a/src/rust/cpu/instructions_0f.rs b/src/rust/cpu/instructions_0f.rs index 55405d208a..2ebc571516 100644 --- a/src/rust/cpu/instructions_0f.rs +++ b/src/rust/cpu/instructions_0f.rs @@ -1,3 +1,5 @@ +#![allow(non_snake_case)] + extern "C" { fn get_rand_int() -> i32; } @@ -552,34 +554,25 @@ pub unsafe fn instr_660F12_mem(addr: i32, r: i32) { write_xmm64(r, data); } #[no_mangle] -pub unsafe fn instr_F20F12(source: reg128, r: i32) { +pub unsafe fn instr_F20F12(source: u64, r: i32) { // movddup xmm1, xmm2/m64 - let destination = read_xmm128s(r); - let result = reg128 { - f64: [ - destination.f64[0] = source.f64[0], - destination.f64[1] = source.f64[0], - ], - }; - write_xmm_reg128(r, result); + write_xmm_reg128(r, reg128 { u64: [source, source] }); } -pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm128s(r1), r2); } +pub unsafe fn instr_F20F12_reg(r1: i32, r2: i32) { instr_F20F12(read_xmm64s(r1), r2); } pub unsafe fn instr_F20F12_mem(addr: i32, r: i32) { - instr_F20F12(return_on_pagefault!(safe_read128s(addr)), r); + instr_F20F12(return_on_pagefault!(safe_read64s(addr)), r); } #[no_mangle] pub unsafe fn instr_F30F12(source: reg128, r: i32) { // movsldup xmm1, xmm2/m128 - let destination = read_xmm128s(r); - let result = reg128 { - f32: [ - destination.f32[0] = source.f32[0], - destination.f32[1] = source.f32[0], - destination.f32[2] = source.f32[2], - destination.f32[3] = source.f32[2], + write_xmm_reg128(r, reg128 { + u32: [ + source.u32[0], + source.u32[0], + source.u32[2], + source.u32[2], ], - }; - write_xmm_reg128(r, result); + }); } pub unsafe fn instr_F30F12_reg(r1: i32, r2: i32) { instr_F30F12(read_xmm128s(r1), r2); } pub unsafe fn instr_F30F12_mem(addr: i32, r: i32) { @@ -683,15 +676,14 @@ pub unsafe fn instr_660F16_reg(_r1: i32, _r2: i32) { trigger_ud(); } #[no_mangle] pub unsafe fn instr_F30F16(source: reg128, r: i32) { // movshdup xmm1, xmm2/m128 - let destination = read_xmm_f32(r); - let result = reg128 { - f32: [ - destination.f32[0] = source.f32[1], - destination.f32[1] = source.f32[1], - destination.f32[2] = source.f32[3], - destination.f32[3] = source.f32[3], + write_xmm_reg128(r, reg128 { + u32: [ + source.u32[1], + source.u32[1], + source.u32[3], + source.u32[3], ] - }; + }); } pub unsafe fn instr_F30F16_reg(r1: i32, r2: i32) { instr_F30F16(read_xmm128s(r1), r2); } pub unsafe fn instr_F30F16_mem(addr: i32, r: i32) { @@ -1856,74 +1848,7 @@ pub unsafe fn instr_F30F59_reg(r1: i32, r2: i32) { instr_F30F59(read_xmm_f32(r1) pub unsafe fn instr_F30F59_mem(addr: i32, r: i32) { instr_F30F59(return_on_pagefault!(safe_read_f32(addr)), r); } -#[no_mangle] -pub unsafe fn instr_660F7C(source: reg128, r: i32) { - // haddpd xmm1, xmm2/m128 - let destination = read_xmm128s(r); - let result = reg128 { - f64: [ - destination.f64[0] + destination.f64[1], - source.f64[0] + source.f64[1], - ], - }; - write_xmm_reg128(r, result); -} -pub unsafe fn instr_660F7C_reg(r1: i32, r2: i32) { instr_660F7C(read_xmm128s(r1), r2); } -pub unsafe fn instr_660F7C_mem(addr: i32, r: i32) { - instr_660F7C(return_on_pagefault!(safe_read128s(addr)), r); -} -#[no_mangle] -pub unsafe fn instr_660F7D(source: reg128, r: i32) { - // hsubpd xmm1, xmm2/m128 - let destination = read_xmm128s(r); - let result = reg128 { - f64: [ - destination.f64[0] - destination.f64[1], - source.f64[0] - source.f64[1], - ], - }; - write_xmm_reg128(r, result); -} -pub unsafe fn instr_660F7D_reg(r1: i32, r2: i32) { instr_660F7D(read_xmm128s(r1), r2); } -pub unsafe fn instr_660F7D_mem(addr: i32, r: i32) { - instr_660F7D(return_on_pagefault!(safe_read128s(addr)), r); -} -#[no_mangle] -pub unsafe fn instr_F20F7C(source: reg128, r: i32) { - // haddps xmm, xmm/mem128 - let destination = read_xmm128s(r); - let result = reg128 { - f32: [ - destination.f32[0] + destination.f32[1], - destination.f32[2] + destination.f32[3], - source.f32[0] + source.f32[1], - source.f32[2] + source.f32[3], - ], - }; - write_xmm_reg128(r, result); -} -pub unsafe fn instr_F20F7C_reg(r1: i32, r2: i32) { instr_F20F7C(read_xmm128s(r1), r2); } -pub unsafe fn instr_F20F7C_mem(addr: i32, r: i32) { - instr_F20F7C(return_on_pagefault!(safe_read128s(addr)), r); -} -#[no_mangle] -pub unsafe fn instr_F20F7D(source: reg128, r: i32) { - // hsubps xmm1, xmm2/m128 - let destination = read_xmm128s(r); - let result = reg128 { - f32: [ - destination.f32[0] - destination.f32[1], - destination.f32[2] - destination.f32[3], - source.f32[0] - source.f32[1], - source.f32[2] - source.f32[3], - ], - }; - write_xmm_reg128(r, result); -} -pub unsafe fn instr_F20F7D_reg(r1: i32, r2: i32) { instr_F20F7D(read_xmm128s(r1), r2); } -pub unsafe fn instr_F20F7D_mem(addr: i32, r: i32) { - instr_F20F7D(return_on_pagefault!(safe_read128s(addr)), r); -} + #[no_mangle] pub unsafe fn instr_0F5A(source: u64, r: i32) { // cvtps2pd xmm1, xmm2/m64 @@ -1941,6 +1866,7 @@ pub unsafe fn instr_0F5A_mem(addr: i32, r: i32) { pub unsafe fn instr_660F5A(source: reg128, r: i32) { // cvtpd2ps xmm1, xmm2/m128 let result = reg128 { + // XXX: These conversions are lossy and should round according to the round control f32: [source.f64[0] as f32, source.f64[1] as f32, 0., 0.], }; write_xmm_reg128(r, result); @@ -2060,7 +1986,7 @@ pub unsafe fn instr_660F5C_mem(addr: i32, r: i32) { } #[no_mangle] pub unsafe fn instr_F20F5C(source: u64, r: i32) { - // subsd xmm1, xmm2/m64 + // subsd xmm, xmm/mem64 let destination = read_xmm64s(r); write_xmm_f64(r, f64::from_bits(destination) - f64::from_bits(source)); } @@ -3029,6 +2955,7 @@ pub unsafe fn instr_0F77() { // emms fpu_set_tag_word(0xFFFF); } + #[no_mangle] pub unsafe fn instr_0F78() { unimplemented_sse(); } #[no_mangle] @@ -3037,11 +2964,79 @@ pub unsafe fn instr_0F79() { unimplemented_sse(); } pub unsafe fn instr_0F7A() { unimplemented_sse(); } #[no_mangle] pub unsafe fn instr_0F7B() { unimplemented_sse(); } + #[no_mangle] pub unsafe fn instr_0F7C() { unimplemented_sse(); } #[no_mangle] pub unsafe fn instr_0F7D() { unimplemented_sse(); } +#[no_mangle] +pub unsafe fn instr_660F7C(source: reg128, r: i32) { + // haddpd xmm1, xmm2/m128 + let destination = read_xmm128s(r); + write_xmm_reg128(r, reg128 { + f64: [ + destination.f64[0] + destination.f64[1], + source.f64[0] + source.f64[1], + ], + }); +} +pub unsafe fn instr_660F7C_reg(r1: i32, r2: i32) { instr_660F7C(read_xmm128s(r1), r2); } +pub unsafe fn instr_660F7C_mem(addr: i32, r: i32) { + instr_660F7C(return_on_pagefault!(safe_read128s(addr)), r); +} +#[no_mangle] +pub unsafe fn instr_F20F7C(source: reg128, r: i32) { + // haddps xmm, xmm/mem128 + let destination = read_xmm128s(r); + write_xmm_reg128(r, reg128 { + f32: [ + destination.f32[0] + destination.f32[1], + destination.f32[2] + destination.f32[3], + source.f32[0] + source.f32[1], + source.f32[2] + source.f32[3], + ], + }); +} +pub unsafe fn instr_F20F7C_reg(r1: i32, r2: i32) { instr_F20F7C(read_xmm128s(r1), r2); } +pub unsafe fn instr_F20F7C_mem(addr: i32, r: i32) { + instr_F20F7C(return_on_pagefault!(safe_read128s(addr)), r); +} + +#[no_mangle] +pub unsafe fn instr_660F7D(source: reg128, r: i32) { + // hsubpd xmm1, xmm2/m128 + let destination = read_xmm128s(r); + write_xmm_reg128(r, reg128 { + f64: [ + destination.f64[0] - destination.f64[1], + source.f64[0] - source.f64[1], + ], + }); +} +pub unsafe fn instr_660F7D_reg(r1: i32, r2: i32) { instr_660F7D(read_xmm128s(r1), r2); } +pub unsafe fn instr_660F7D_mem(addr: i32, r: i32) { + instr_660F7D(return_on_pagefault!(safe_read128s(addr)), r); +} + +#[no_mangle] +pub unsafe fn instr_F20F7D(source: reg128, r: i32) { + // hsubps xmm1, xmm2/m128 + let destination = read_xmm128s(r); + write_xmm_reg128(r, reg128 { + f32: [ + destination.f32[0] - destination.f32[1], + destination.f32[2] - destination.f32[3], + source.f32[0] - source.f32[1], + source.f32[2] - source.f32[3], + ], + }); +} +pub unsafe fn instr_F20F7D_reg(r1: i32, r2: i32) { instr_F20F7D(read_xmm128s(r1), r2); } +pub unsafe fn instr_F20F7D_mem(addr: i32, r: i32) { + instr_F20F7D(return_on_pagefault!(safe_read128s(addr)), r); +} + #[no_mangle] pub unsafe fn instr_0F7E(r: i32) -> i32 { // movd r/m32, mm @@ -3213,7 +3208,7 @@ pub unsafe fn instr_0FA2() { let mut ebx = 0; let level = read_reg32(EAX) as u32; - + match level { 0 => { // maximum supported level (default 0x16, overwritten to 2 as a workaround for Windows NT) @@ -3228,7 +3223,7 @@ pub unsafe fn instr_0FA2() { // pentium eax = 3 | 6 << 4 | 15 << 8; ebx = 1 << 16 | 8 << 8; // cpu count, clflush size - ecx = 1 << 0 | 1 << 23 | 1 << 30; // popcnt, rdrand, sse3 + ecx = 1 << 0 | 1 << 23 | 1 << 30; // sse3, popcnt, rdrand let vme = 0 << 1; if ::config::VMWARE_HYPERVISOR_PORT { ecx |= 1 << 31 diff --git a/src/rust/jit_instructions.rs b/src/rust/jit_instructions.rs index 87ab1ce33c..635b039b28 100644 --- a/src/rust/jit_instructions.rs +++ b/src/rust/jit_instructions.rs @@ -3852,6 +3852,7 @@ pub fn instr32_DD_0_reg_jit(ctx: &mut JitContext, r: u32) { instr16_DD_0_reg_jit pub fn instr32_DD_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { instr16_DD_0_mem_jit(ctx, modrm_byte) } + pub fn instr16_DD_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { codegen::gen_modrm_resolve(ctx, modrm_byte); let address_local = ctx.builder.set_new_local(); @@ -5673,16 +5674,6 @@ pub fn instr_F20F10_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { ctx.builder .store_aligned_i64(global_pointers::get_reg_xmm_offset(r2)); } -pub fn instr_F20F12_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { - instr_F30F7E_mem_jit(ctx, modrm_byte, r) -} -pub fn instr_F20F12_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { - ctx.builder.const_i32(0); - ctx.builder - .load_fixed_i64(global_pointers::get_reg_xmm_offset(r1)); - ctx.builder - .store_aligned_i64(global_pointers::get_reg_xmm_offset(r2)); -} pub fn instr_F30F10_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { instr_660F6E_mem_jit(ctx, modrm_byte, r) } @@ -5693,26 +5684,7 @@ pub fn instr_F30F10_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { ctx.builder .store_aligned_i32(global_pointers::get_reg_xmm_offset(r2)); } -pub fn instr_F30F12_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { - sse_read128_xmm_mem(ctx, "instr_660F6E", modrm_byte, r); -} -pub fn instr_F30F12_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { - ctx.builder.const_i32(0); - ctx.builder - .load_fixed_i32(global_pointers::get_reg_xmm_offset(r1)); - ctx.builder - .store_aligned_i32(global_pointers::get_reg_xmm_offset(r2)); -} -pub fn instr_F30F16_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { - instr_660F6E_mem_jit(ctx, modrm_byte, r) -} -pub fn instr_F30F16_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { - ctx.builder.const_i32(0); - ctx.builder - .load_fixed_i32(global_pointers::get_reg_xmm_offset(r1)); - ctx.builder - .store_aligned_i32(global_pointers::get_reg_xmm_offset(r2)); -} + pub fn instr_0F11_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { instr_0F29_mem_jit(ctx, modrm_byte, r) } @@ -5766,6 +5738,19 @@ pub fn instr_660F12_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) { codegen::gen_trigger_ud(ctx); } +pub fn instr_F20F12_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { + sse_read64_xmm_mem(ctx, "instr_F20F12", modrm_byte, r); +} +pub fn instr_F20F12_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { + sse_read64_xmm_xmm(ctx, "instr_F20F12", r1, r2); +} +pub fn instr_F30F12_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { + sse_read128_xmm_mem(ctx, "instr_F30F12", modrm_byte, r); +} +pub fn instr_F30F12_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { + sse_read128_xmm_xmm(ctx, "instr_F30F12", r1, r2); +} + pub fn instr_0F13_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { instr_660FD6_mem_jit(ctx, modrm_byte, r) } @@ -5818,6 +5803,13 @@ pub fn instr_660F16_reg_jit(ctx: &mut JitContext, _r1: u32, _r2: u32) { codegen::gen_trigger_ud(ctx); } +pub fn instr_F30F16_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { + sse_read128_xmm_mem(ctx, "instr_F30F16", modrm_byte, r); +} +pub fn instr_F30F16_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { + sse_read128_xmm_xmm(ctx, "instr_F30F16", r1, r2); +} + pub fn instr_0F17_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { codegen::gen_modrm_resolve(ctx, modrm_byte); let address_local = ctx.builder.set_new_local(); @@ -6156,18 +6148,7 @@ pub fn instr_F30F59_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) pub fn instr_F30F59_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_read_f32_xmm_xmm(ctx, "instr_F30F59", r1, r2); } -pub fn instr_F20F7C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { - sse_read128_xmm_mem(ctx, "instr_F20F7C", modrm_byte, r); -} -pub fn instr_F20F7C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { - sse_read128_xmm_xmm(ctx, "instr_F20F7C", r1, r2); -} -pub fn instr_F20F7D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { - sse_read128_xmm_mem(ctx, "instr_F20F7D", modrm_byte, r); -} -pub fn instr_F20F7D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { - sse_read128_xmm_xmm(ctx, "instr_F20F7D", r1, r2); -} + pub fn instr_0F5A_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { sse_read64_xmm_mem(ctx, "instr_0F5A", modrm_byte, r); } @@ -6205,18 +6186,6 @@ pub fn instr_660F5B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) pub fn instr_660F5B_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_read128_xmm_xmm(ctx, "instr_660F5B", r1, r2); } -pub fn instr_660F7D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { - sse_read128_xmm_mem(ctx, "instr_660F7D", modrm_byte, r); -} -pub fn instr_660F7D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { - sse_read128_xmm_xmm(ctx, "instr_660F7D", r1, r2); -} -pub fn instr_660F7C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { - sse_read128_xmm_mem(ctx, "instr_660F7C", modrm_byte, r); -} -pub fn instr_660F7C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { - sse_read128_xmm_xmm(ctx, "instr_660F7C", r1, r2); -} pub fn instr_F30F5B_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { sse_read128_xmm_mem(ctx, "instr_F30F5B", modrm_byte, r); } @@ -6811,6 +6780,31 @@ pub fn instr_660F76_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { sse_read128_xmm_xmm(ctx, "instr_660F76", r1, r2); } +pub fn instr_660F7C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { + sse_read128_xmm_mem(ctx, "instr_660F7C", modrm_byte, r); +} +pub fn instr_660F7C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { + sse_read128_xmm_xmm(ctx, "instr_660F7C", r1, r2); +} +pub fn instr_F20F7C_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { + sse_read128_xmm_mem(ctx, "instr_F20F7C", modrm_byte, r); +} +pub fn instr_F20F7C_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { + sse_read128_xmm_xmm(ctx, "instr_F20F7C", r1, r2); +} +pub fn instr_660F7D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { + sse_read128_xmm_mem(ctx, "instr_660F7D", modrm_byte, r); +} +pub fn instr_660F7D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { + sse_read128_xmm_xmm(ctx, "instr_660F7D", r1, r2); +} +pub fn instr_F20F7D_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { + sse_read128_xmm_mem(ctx, "instr_F20F7D", modrm_byte, r); +} +pub fn instr_F20F7D_reg_jit(ctx: &mut JitContext, r1: u32, r2: u32) { + sse_read128_xmm_xmm(ctx, "instr_F20F7D", r1, r2); +} + pub fn instr_0F7E_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, r: u32) { codegen::gen_modrm_resolve(ctx, modrm_byte); let address_local = ctx.builder.set_new_local(); diff --git a/src/rust/lib.rs b/src/rust/lib.rs index 60c915c6fb..ebd3b89ab6 100644 --- a/src/rust/lib.rs +++ b/src/rust/lib.rs @@ -1,5 +1,3 @@ -#![allow(nonstandard_style)] - #![allow(const_item_mutation)] #[macro_use] diff --git a/src/rust/softfloat.rs b/src/rust/softfloat.rs index 782146c52b..b97d7761a2 100644 --- a/src/rust/softfloat.rs +++ b/src/rust/softfloat.rs @@ -129,6 +129,9 @@ impl F80 { pub fn to_i32(&self) -> i32 { unsafe { extF80M_to_i32(self, softfloat_roundingMode, false) } } pub fn to_i64(&self) -> i64 { unsafe { extF80M_to_i64(self, softfloat_roundingMode, false) } } + pub fn truncate_to_i32(&self) -> i32 { unsafe { extF80M_to_i32(self, 1, false) } } + pub fn truncate_to_i64(&self) -> i64 { unsafe { extF80M_to_i64(self, 1, false) } } + pub fn cos(self) -> F80 { F80::of_f64x(self.to_f64x().cos()) } pub fn sin(self) -> F80 { F80::of_f64x(self.to_f64x().sin()) } pub fn tan(self) -> F80 { F80::of_f64x(self.to_f64x().tan()) }