From 753a6d1fb33728bd716d8ec4e6677d46df4c9c9e Mon Sep 17 00:00:00 2001 From: Fabian Date: Wed, 9 Nov 2022 12:12:34 -0600 Subject: [PATCH] jit: handle fpu DA group --- gen/x86_table.js | 14 ++++----- src/rust/cpu/instructions.rs | 11 ------- src/rust/jit_instructions.rs | 56 +++++++++++++++++++++++++++++++----- 3 files changed, 56 insertions(+), 25 deletions(-) diff --git a/gen/x86_table.js b/gen/x86_table.js index 16a8a6c2..e06b6f6b 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -296,14 +296,14 @@ const encodings = [ { opcode: 0xD9, e: 1, fixed_g: 6, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, skip: 1, }, // fstenv (mem), fprem (reg) { opcode: 0xD9, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, skip_reg: 1, }, // fprem, fyl2xp1 (precision issues) - { opcode: 0xDA, e: 1, fixed_g: 0, custom: 0, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDA, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDA, e: 1, fixed_g: 2, custom: 0, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDA, e: 1, fixed_g: 3, custom: 0, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDA, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, }, + { opcode: 0xDA, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, }, + { opcode: 0xDA, e: 1, fixed_g: 1, custom: 1, is_fpu: 1, task_switch_test: 1, }, + { opcode: 0xDA, e: 1, fixed_g: 2, custom: 1, is_fpu: 1, task_switch_test: 1, }, + { opcode: 0xDA, e: 1, fixed_g: 3, custom: 1, is_fpu: 1, task_switch_test: 1, }, + { opcode: 0xDA, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, }, { opcode: 0xDA, e: 1, fixed_g: 5, custom: 1, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDA, e: 1, fixed_g: 6, custom: 0, is_fpu: 1, task_switch_test: 1, }, - { opcode: 0xDA, e: 1, fixed_g: 7, custom: 0, is_fpu: 1, task_switch_test: 1, }, + { opcode: 0xDA, e: 1, fixed_g: 6, custom: 1, is_fpu: 1, task_switch_test: 1, }, + { 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) diff --git a/src/rust/cpu/instructions.rs b/src/rust/cpu/instructions.rs index a01c05ae..8d895888 100644 --- a/src/rust/cpu/instructions.rs +++ b/src/rust/cpu/instructions.rs @@ -1793,21 +1793,13 @@ 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) } -#[no_mangle] pub unsafe fn instr_DA_0_mem(addr: i32) { fpu_fadd(0, return_on_pagefault!(fpu_load_i32(addr))); } -#[no_mangle] pub unsafe fn instr_DA_1_mem(addr: i32) { fpu_fmul(0, return_on_pagefault!(fpu_load_i32(addr))); } -#[no_mangle] pub unsafe fn instr_DA_2_mem(addr: i32) { fpu_fcom(return_on_pagefault!(fpu_load_i32(addr))); } -#[no_mangle] pub unsafe fn instr_DA_3_mem(addr: i32) { fpu_fcomp(return_on_pagefault!(fpu_load_i32(addr))); } -#[no_mangle] pub unsafe fn instr_DA_4_mem(addr: i32) { fpu_fsub(0, return_on_pagefault!(fpu_load_i32(addr))); } -#[no_mangle] pub unsafe fn instr_DA_5_mem(addr: i32) { fpu_fsubr(0, return_on_pagefault!(fpu_load_i32(addr))); } -#[no_mangle] pub unsafe fn instr_DA_6_mem(addr: i32) { fpu_fdiv(0, return_on_pagefault!(fpu_load_i32(addr))); } -#[no_mangle] 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); } @@ -1817,7 +1809,6 @@ pub unsafe fn instr_DA_1_reg(r: i32) { fpu_fcmovcc(test_z(), r); } 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); } -#[no_mangle] pub unsafe fn instr_DA_4_reg(_r: i32) { trigger_ud(); } pub unsafe fn instr_DA_5_reg(r: i32) { if r == 1 { @@ -1827,9 +1818,7 @@ pub unsafe fn instr_DA_5_reg(r: i32) { trigger_ud(); }; } -#[no_mangle] pub unsafe fn instr_DA_6_reg(_r: i32) { trigger_ud(); } -#[no_mangle] pub unsafe fn instr_DA_7_reg(_r: i32) { trigger_ud(); } pub unsafe fn instr_DB_0_mem(addr: i32) { fpu_fildm32(addr); } diff --git a/src/rust/jit_instructions.rs b/src/rust/jit_instructions.rs index c5defbf4..61f5a1de 100644 --- a/src/rust/jit_instructions.rs +++ b/src/rust/jit_instructions.rs @@ -3612,18 +3612,60 @@ pub fn instr32_D9_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { instr16_D9_7_mem_jit(ctx, modrm_byte) } -pub fn instr_DA_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { - ctx.builder.const_i32(0); - codegen::gen_fpu_load_i32(ctx, modrm_byte); - ctx.builder.call_fn3_i32_i64_i32("fpu_fsubr") +pub fn instr_DA_0_reg_jit(ctx: &mut JitContext, r: u32) { + codegen::gen_fn1_const(ctx.builder, "instr_DA_0_reg", r); } +pub fn instr_DA_1_reg_jit(ctx: &mut JitContext, r: u32) { + codegen::gen_fn1_const(ctx.builder, "instr_DA_1_reg", r); +} +pub fn instr_DA_2_reg_jit(ctx: &mut JitContext, r: u32) { + codegen::gen_fn1_const(ctx.builder, "instr_DA_2_reg", r); +} +pub fn instr_DA_3_reg_jit(ctx: &mut JitContext, r: u32) { + codegen::gen_fn1_const(ctx.builder, "instr_DA_3_reg", r); +} +pub fn instr_DA_4_reg_jit(ctx: &mut JitContext, _r: u32) { codegen::gen_trigger_ud(ctx) } pub fn instr_DA_5_reg_jit(ctx: &mut JitContext, r: u32) { if r == 1 { - codegen::gen_fn0_const(ctx.builder, "fpu_fucompp"); + codegen::gen_fn0_const(ctx.builder, "fpu_fucompp") } else { - codegen::gen_trigger_ud(ctx); - }; + codegen::gen_trigger_ud(ctx) + } +} +pub fn instr_DA_6_reg_jit(ctx: &mut JitContext, _r: u32) { codegen::gen_trigger_ud(ctx) } +pub fn instr_DA_7_reg_jit(ctx: &mut JitContext, _r: u32) { codegen::gen_trigger_ud(ctx) } + +pub fn instr_group_DA_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte, op: &str) { + ctx.builder.const_i32(0); + codegen::gen_fpu_load_i32(ctx, modrm_byte); + ctx.builder.call_fn3_i32_i64_i32(op) +} +pub fn instr_DA_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { + instr_group_DA_mem_jit(ctx, modrm_byte, "fpu_fadd") +} +pub fn instr_DA_1_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { + instr_group_DA_mem_jit(ctx, modrm_byte, "fpu_fmul") +} +pub fn instr_DA_2_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { + codegen::gen_fpu_load_i32(ctx, modrm_byte); + ctx.builder.call_fn2_i64_i32("fpu_fcom") +} +pub fn instr_DA_3_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { + codegen::gen_fpu_load_i32(ctx, modrm_byte); + ctx.builder.call_fn2_i64_i32("fpu_fcomp") +} +pub fn instr_DA_4_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { + instr_group_DA_mem_jit(ctx, modrm_byte, "fpu_fsub") +} +pub fn instr_DA_5_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { + instr_group_DA_mem_jit(ctx, modrm_byte, "fpu_fsubr") +} +pub fn instr_DA_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { + instr_group_DA_mem_jit(ctx, modrm_byte, "fpu_fdiv") +} +pub fn instr_DA_7_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) { + instr_group_DA_mem_jit(ctx, modrm_byte, "fpu_fdivr") } pub fn instr_DB_0_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {