implement fbstp (close #708)
This commit is contained in:
parent
cf31709ec5
commit
f1ebdb1c72
|
@ -346,9 +346,9 @@ const encodings = [
|
|||
{ 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, skip_mem: 1 }, // unimplemented: Binary Coded Decimals
|
||||
{ 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, },
|
||||
|
|
|
@ -625,6 +625,35 @@ pub unsafe fn fpu_fstp(r: i32) {
|
|||
fpu_pop();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn fpu_fbstp(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();
|
||||
|
|
|
@ -1989,11 +1989,7 @@ pub unsafe fn instr_DF_4_mem(_addr: i32) {
|
|||
fpu_unimpl();
|
||||
}
|
||||
pub unsafe fn instr_DF_5_mem(addr: i32) { fpu_fildm64(addr); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_DF_6_mem(_addr: i32) {
|
||||
dbg_log!("fbstp");
|
||||
fpu_unimpl();
|
||||
}
|
||||
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]
|
||||
|
@ -2014,7 +2010,6 @@ pub unsafe fn instr_DF_4_reg(r: i32) {
|
|||
};
|
||||
}
|
||||
pub unsafe fn instr_DF_5_reg(r: i32) { fpu_fucomip(r); }
|
||||
#[no_mangle]
|
||||
pub unsafe fn instr_DF_6_reg(r: i32) { fpu_fcomip(r); }
|
||||
pub unsafe fn instr_DF_7_reg(_r: i32) { trigger_ud(); }
|
||||
|
||||
|
|
|
@ -3776,9 +3776,22 @@ pub fn instr_DF_5_reg_jit(ctx: &mut JitContext, r: u32) {
|
|||
}
|
||||
|
||||
pub fn instr_DF_6_mem_jit(ctx: &mut JitContext, modrm_byte: ModrmByte) {
|
||||
dbg_log!("fbstp");
|
||||
codegen::gen_modrm_resolve(ctx, modrm_byte);
|
||||
codegen::gen_trigger_ud(ctx);
|
||||
|
||||
codegen::gen_set_previous_eip_offset_from_eip_with_low_bits(
|
||||
ctx.builder,
|
||||
ctx.start_of_current_instruction as i32 & 0xFFF,
|
||||
);
|
||||
|
||||
codegen::gen_move_registers_from_locals_to_memory(ctx);
|
||||
ctx.builder.call_fn1("fpu_fbstp");
|
||||
codegen::gen_move_registers_from_memory_to_locals(ctx);
|
||||
|
||||
codegen::gen_get_page_fault(ctx.builder);
|
||||
ctx.builder.if_void();
|
||||
codegen::gen_debug_track_jit_exit(ctx.builder, ctx.start_of_current_instruction);
|
||||
ctx.builder.br(ctx.exit_label);
|
||||
ctx.builder.block_end();
|
||||
}
|
||||
pub fn instr_DF_6_reg_jit(ctx: &mut JitContext, r: u32) {
|
||||
ctx.builder.const_i32(r as i32);
|
||||
|
|
|
@ -1050,7 +1050,7 @@ void test_fbcd(double a)
|
|||
double b;
|
||||
|
||||
asm("fbstp %0" : "=m" (bcd[0]) : "t" (a) : "st");
|
||||
asm("fbld %1" : "=t" (b) : "m" (bcd[0]));
|
||||
//asm("fbld %1" : "=t" (b) : "m" (bcd[0]));
|
||||
printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n",
|
||||
a, bcd[4], bcd[3], bcd[2], bcd[1], bcd[0], b);
|
||||
}
|
||||
|
@ -1180,8 +1180,18 @@ void test_floats(void)
|
|||
test_fcvt(1.0/0.0);
|
||||
test_fcvt(q_nan.d);
|
||||
test_fconst();
|
||||
//test_fbcd(1234567890123456.0);
|
||||
//test_fbcd(-123451234567890.0);
|
||||
test_fbcd(0.0);
|
||||
test_fbcd(-0.0);
|
||||
test_fbcd(1.0);
|
||||
test_fbcd(-1.0);
|
||||
test_fbcd(1234567890123456.0);
|
||||
test_fbcd(-123451234567890.0);
|
||||
test_fbcd(341234567890123456.0);
|
||||
test_fbcd(-345123451234567890.0);
|
||||
test_fbcd(999999999999999900.0);
|
||||
test_fbcd(-999999999999999900.0);
|
||||
test_fbcd(1000000000000000000.0);
|
||||
test_fbcd(-1000000000000000000.0);
|
||||
test_fenv();
|
||||
if (TEST_CMOV) {
|
||||
test_fcmov();
|
||||
|
|
Loading…
Reference in a new issue