Codegen for fpu instructions (memory loads: fld, fild) (D9_0, DB_0, DD_0, DF_5)

This commit is contained in:
Fabian 2018-12-03 18:09:41 -06:00
parent c452c357dd
commit 7c99bdae74
3 changed files with 45 additions and 4 deletions

View file

@ -282,7 +282,7 @@ const encodings = [
{ opcode: 0xD8, e: 1, fixed_g: 6, custom: 1, is_fpu: 1, task_switch_test: 1, },
{ opcode: 0xD8, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, },
{ opcode: 0xD9, e: 1, fixed_g: 0, custom: 0, is_fpu: 1, task_switch_test: 1, },
{ opcode: 0xD9, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, },
{ opcode: 0xD9, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, },
{ opcode: 0xD9, e: 1, fixed_g: 2, custom: 0, is_fpu: 1, task_switch_test: 1, },
{ opcode: 0xD9, e: 1, fixed_g: 3, custom: 0, is_fpu: 1, task_switch_test: 1, },
@ -300,7 +300,7 @@ const encodings = [
{ 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: 0xDB, e: 1, fixed_g: 0, custom: 0, 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, only_reg: 1, }, // unimplemented: fisttp (sse3)
{ opcode: 0xDB, e: 1, fixed_g: 2, custom: 0, is_fpu: 1, task_switch_test: 1, },
{ opcode: 0xDB, e: 1, fixed_g: 3, custom: 0, is_fpu: 1, task_switch_test: 1, },
@ -318,7 +318,7 @@ const encodings = [
{ opcode: 0xDC, e: 1, fixed_g: 6, custom: 1, is_fpu: 1, task_switch_test: 1, },
{ opcode: 0xDC, e: 1, fixed_g: 7, custom: 1, is_fpu: 1, task_switch_test: 1, },
{ opcode: 0xDD, e: 1, fixed_g: 0, custom: 0, is_fpu: 1, task_switch_test: 1, },
{ opcode: 0xDD, e: 1, fixed_g: 0, custom: 1, is_fpu: 1, task_switch_test: 1, },
{ opcode: 0xDD, e: 1, fixed_g: 1, custom: 0, is_fpu: 1, task_switch_test: 1, only_reg: 1, }, // XXX: Test should fail
{ opcode: 0xDD, e: 1, fixed_g: 2, custom: 0, is_fpu: 1, task_switch_test: 1, },
{ opcode: 0xDD, e: 1, fixed_g: 3, custom: 0, is_fpu: 1, task_switch_test: 1, },
@ -341,7 +341,7 @@ const encodings = [
{ opcode: 0xDF, e: 1, fixed_g: 2, custom: 0, is_fpu: 1, task_switch_test: 1 },
{ opcode: 0xDF, e: 1, fixed_g: 3, custom: 0, is_fpu: 1, task_switch_test: 1 },
{ opcode: 0xDF, e: 1, fixed_g: 4, custom: 0, is_fpu: 1, task_switch_test: 1, only_reg: 1 }, // mem exists, but not implemented
{ opcode: 0xDF, e: 1, fixed_g: 5, custom: 0, 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: 0, is_fpu: 1, task_switch_test: 1, only_reg: 1 }, // mem exists, but not implemented
{ opcode: 0xDF, e: 1, fixed_g: 7, custom: 0, is_fpu: 1, task_switch_test: 1, },

View file

@ -1917,6 +1917,26 @@ pub fn instr_D8_7_reg_jit(ctx: &mut JitContext, r: u32) {
instr_group_D8_reg_jit(ctx, r, "fpu_fdivr")
}
pub fn instr_D9_0_mem_jit(ctx: &mut JitContext, modrm_byte: u8) {
codegen::gen_modrm_resolve(ctx, modrm_byte);
codegen::gen_fpu_load_m32(ctx);
codegen::gen_call_fn1_f64(ctx.builder, "fpu_push");
}
pub fn instr_D9_0_reg_jit(ctx: &mut JitContext, r: u32) {
codegen::gen_fpu_get_sti(ctx, r);
codegen::gen_call_fn1_f64(ctx.builder, "fpu_push");
}
pub fn instr_DB_0_mem_jit(ctx: &mut JitContext, modrm_byte: u8) {
codegen::gen_modrm_resolve(ctx, modrm_byte);
codegen::gen_safe_read32(ctx);
ctx.builder.instruction_body.convert_i32_to_f64();
codegen::gen_call_fn1_f64(ctx.builder, "fpu_push");
}
pub fn instr_DB_0_reg_jit(ctx: &mut JitContext, r: u32) {
codegen::gen_fn1_const(ctx.builder, "instr_DB_0_reg", r);
}
fn instr_group_DC_mem_jit(ctx: &mut JitContext, modrm_byte: u8, op: &str) {
ctx.builder.instruction_body.const_i32(0);
codegen::gen_modrm_resolve(ctx, modrm_byte);
@ -1984,6 +2004,15 @@ pub fn instr_DC_7_reg_jit(ctx: &mut JitContext, r: u32) {
instr_group_DC_reg_jit(ctx, r, "fpu_fdivr")
}
pub fn instr_DD_0_mem_jit(ctx: &mut JitContext, modrm_byte: u8) {
codegen::gen_modrm_resolve(ctx, modrm_byte);
codegen::gen_fpu_load_m64(ctx);
codegen::gen_call_fn1_f64(ctx.builder, "fpu_push");
}
pub fn instr_DD_0_reg_jit(ctx: &mut JitContext, r: u32) {
codegen::gen_fn1_const(ctx.builder, "fpu_ffree", r);
}
fn instr_group_DE_mem_jit(ctx: &mut JitContext, modrm_byte: u8, op: &str) {
ctx.builder.instruction_body.const_i32(0);
codegen::gen_modrm_resolve(ctx, modrm_byte);
@ -2065,6 +2094,16 @@ 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_5_mem_jit(ctx: &mut JitContext, modrm_byte: u8) {
codegen::gen_modrm_resolve(ctx, modrm_byte);
codegen::gen_safe_read64(ctx);
ctx.builder.instruction_body.convert_i64_to_f64();
codegen::gen_call_fn1_f64(ctx.builder, "fpu_push");
}
pub fn instr_DF_5_reg_jit(ctx: &mut JitContext, r: u32) {
codegen::gen_fn1_const(ctx.builder, "fpu_fucomip", r);
}
pub fn instr16_EB_jit(ctx: &mut JitContext, imm8: u32) {
codegen::gen_jmp_rel16(ctx.builder, imm8 as u16);
// dbg_assert(is_asize_32() || get_real_eip() < 0x10000);

View file

@ -46,6 +46,7 @@ pub trait WasmBuf {
fn reinterpret_i64_as_f64(&mut self);
fn promote_f32_to_f64(&mut self);
fn convert_i32_to_f64(&mut self);
fn convert_i64_to_f64(&mut self);
fn shr_u_i32(&mut self);
fn shr_s_i32(&mut self);
@ -225,6 +226,7 @@ impl WasmBuf for Vec<u8> {
fn reinterpret_i64_as_f64(&mut self) { self.push(op::OP_F64REINTERPRETI64); }
fn promote_f32_to_f64(&mut self) { self.push(op::OP_F64PROMOTEF32); }
fn convert_i32_to_f64(&mut self) { self.push(op::OP_F64CONVERTSI32); }
fn convert_i64_to_f64(&mut self) { self.push(op::OP_F64CONVERTSI64); }
fn shr_u_i32(&mut self) { self.push(op::OP_I32SHRU); }