From 4e49468b7bc930ec4c5eec85a510e38669d45fba Mon Sep 17 00:00:00 2001 From: Fabian Date: Thu, 31 Dec 2020 19:14:30 -0600 Subject: [PATCH] Fix some minor fpu bugs and add more nasm tests --- gen/x86_table.js | 2 +- src/rust/cpu2/fpu.rs | 12 ++++++++++++ src/rust/cpu2/instructions.rs | 4 +++- tests/nasm/f2xm1.asm | 19 +++++++++++++++++++ tests/nasm/fdecstp.asm | 8 ++++++++ tests/nasm/fincstp.asm | 8 ++++++++ tests/nasm/fprem.asm | 21 +++++++++++++++++++++ tests/nasm/fprem1.asm | 21 +++++++++++++++++++++ tests/nasm/fptan.asm | 13 +++++++++++++ tests/nasm/frndint.asm | 18 ++++++++++++++++++ tests/nasm/fscale.asm | 10 ++++++++++ tests/nasm/fsincos.asm | 20 ++++++++++++++++++++ tests/nasm/fsqrt.asm | 9 +++++++++ tests/nasm/fyl2x.asm | 10 ++++++++++ tests/nasm/fyl2xp1.asm | 9 +++++++++ tests/nasm/indirect-call.asm | 14 ++++++++++++++ tests/nasm/indirect-jump.asm | 12 ++++++++++++ tests/nasm/pop_esp2.asm | 12 ++++++++++++ 18 files changed, 220 insertions(+), 2 deletions(-) create mode 100644 tests/nasm/f2xm1.asm create mode 100644 tests/nasm/fdecstp.asm create mode 100644 tests/nasm/fincstp.asm create mode 100644 tests/nasm/fprem.asm create mode 100644 tests/nasm/fprem1.asm create mode 100644 tests/nasm/fptan.asm create mode 100644 tests/nasm/frndint.asm create mode 100644 tests/nasm/fscale.asm create mode 100644 tests/nasm/fsincos.asm create mode 100644 tests/nasm/fsqrt.asm create mode 100644 tests/nasm/fyl2x.asm create mode 100644 tests/nasm/fyl2xp1.asm create mode 100644 tests/nasm/indirect-call.asm create mode 100644 tests/nasm/indirect-jump.asm create mode 100644 tests/nasm/pop_esp2.asm diff --git a/gen/x86_table.js b/gen/x86_table.js index 29e9d59b..b8e3ccad 100644 --- a/gen/x86_table.js +++ b/gen/x86_table.js @@ -287,7 +287,7 @@ const encodings = [ { opcode: 0xD9, e: 1, fixed_g: 4, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, skip_mem: 1, }, // fldenv (mem) { opcode: 0xD9, e: 1, fixed_g: 5, custom: 1, is_fpu: 1, task_switch_test: 1, os: 1, }, { 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 + { 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, }, diff --git a/src/rust/cpu2/fpu.rs b/src/rust/cpu2/fpu.rs index f93d890d..f2139243 100644 --- a/src/rust/cpu2/fpu.rs +++ b/src/rust/cpu2/fpu.rs @@ -516,6 +516,18 @@ pub unsafe fn fpu_fprem(ieee: bool) { let st0 = fpu_get_st0(); let st1 = fpu_get_sti(1); + + if st1 == 0.0 { + if st0 == 0.0 { + fpu_invalid_arithmetic(); + } + else { + fpu_zero_fault(); + } + fpu_write_st(*fpu_stack_ptr as i32, INDEFINITE_NAN); + return; + } + let exp0 = st0.log2(); let exp1 = st1.log2(); let d = (exp0 - exp1).abs(); diff --git a/src/rust/cpu2/instructions.rs b/src/rust/cpu2/instructions.rs index 2b6ba639..48cfd176 100644 --- a/src/rust/cpu2/instructions.rs +++ b/src/rust/cpu2/instructions.rs @@ -3348,10 +3348,10 @@ 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) { - let st0 = fpu_get_st0(); match r { 0 => { // f2xm1 + let st0 = fpu_get_st0(); let mut r = pow(2.0, st0) - 1.0; if r == -1.0 { // Intel ... @@ -3365,6 +3365,7 @@ pub unsafe fn instr16_D9_6_reg(r: i32) { }, 2 => { // fptan + let st0 = fpu_get_st0(); if pow(-2.0, 63.0) < st0 && st0 < pow(2.0, 63.0) { fpu_write_st(*fpu_stack_ptr as i32, st0.tan()); // no bug: push constant 1 @@ -3377,6 +3378,7 @@ pub unsafe fn instr16_D9_6_reg(r: i32) { }, 3 => { // fpatan + let st0 = fpu_get_st0(); fpu_write_st(*fpu_stack_ptr as i32 + 1 & 7, fpu_get_sti(1).atan2(st0)); fpu_pop(); }, diff --git a/tests/nasm/f2xm1.asm b/tests/nasm/f2xm1.asm new file mode 100644 index 00000000..18d95e9c --- /dev/null +++ b/tests/nasm/f2xm1.asm @@ -0,0 +1,19 @@ +global _start + +%include "header.inc" + + fldz + f2xm1 + + fld1 + f2xm1 + + fld1 + fchs + f2xm1 + + fldln2 + f2xm1 + +%include "footer.inc" + diff --git a/tests/nasm/fdecstp.asm b/tests/nasm/fdecstp.asm new file mode 100644 index 00000000..f24cbd7f --- /dev/null +++ b/tests/nasm/fdecstp.asm @@ -0,0 +1,8 @@ +global _start + +%include "header.inc" + + fdecstp + +%include "footer.inc" + diff --git a/tests/nasm/fincstp.asm b/tests/nasm/fincstp.asm new file mode 100644 index 00000000..79ccc470 --- /dev/null +++ b/tests/nasm/fincstp.asm @@ -0,0 +1,8 @@ +global _start + +%include "header.inc" + + fincstp + +%include "footer.inc" + diff --git a/tests/nasm/fprem.asm b/tests/nasm/fprem.asm new file mode 100644 index 00000000..bd14d89c --- /dev/null +++ b/tests/nasm/fprem.asm @@ -0,0 +1,21 @@ +global _start + +%include "header.inc" + + fld1 + fldz + fprem + + fld1 + fldpi + fprem + + fld1 + fldl2t + fprem + + fldz + fldz + fprem + +%include "footer.inc" diff --git a/tests/nasm/fprem1.asm b/tests/nasm/fprem1.asm new file mode 100644 index 00000000..645043da --- /dev/null +++ b/tests/nasm/fprem1.asm @@ -0,0 +1,21 @@ +global _start + +%include "header.inc" + + fld1 + fldz + fprem1 + + fld1 + fldpi + fprem1 + + fld1 + fldl2t + fprem1 + + fldz + fldz + fprem1 + +%include "footer.inc" diff --git a/tests/nasm/fptan.asm b/tests/nasm/fptan.asm new file mode 100644 index 00000000..50d35b0f --- /dev/null +++ b/tests/nasm/fptan.asm @@ -0,0 +1,13 @@ +global _start + +%include "header.inc" + + fldpi + fptan + + fldpi + fldpi + fpatan + +%include "footer.inc" + diff --git a/tests/nasm/frndint.asm b/tests/nasm/frndint.asm new file mode 100644 index 00000000..680353f0 --- /dev/null +++ b/tests/nasm/frndint.asm @@ -0,0 +1,18 @@ +global _start + +%include "header.inc" + + fldz + frndint + + fldpi + frndint + + fldl2t + frndint + + fldln2 + frndint + +%include "footer.inc" + diff --git a/tests/nasm/fscale.asm b/tests/nasm/fscale.asm new file mode 100644 index 00000000..af0f07a5 --- /dev/null +++ b/tests/nasm/fscale.asm @@ -0,0 +1,10 @@ +global _start + +%include "header.inc" + + fldpi + fldpi + fscale + +%include "footer.inc" + diff --git a/tests/nasm/fsincos.asm b/tests/nasm/fsincos.asm new file mode 100644 index 00000000..751a3cca --- /dev/null +++ b/tests/nasm/fsincos.asm @@ -0,0 +1,20 @@ +global _start + +%include "header.inc" + + fldpi + fsincos + fldz + fsincos + + fldpi + fsin + fldz + fsin + + fldpi + fcos + fldz + fcos + +%include "footer.inc" diff --git a/tests/nasm/fsqrt.asm b/tests/nasm/fsqrt.asm new file mode 100644 index 00000000..653366dd --- /dev/null +++ b/tests/nasm/fsqrt.asm @@ -0,0 +1,9 @@ +global _start + +%include "header.inc" + + fldpi + fsqrt + +%include "footer.inc" + diff --git a/tests/nasm/fyl2x.asm b/tests/nasm/fyl2x.asm new file mode 100644 index 00000000..ae038e45 --- /dev/null +++ b/tests/nasm/fyl2x.asm @@ -0,0 +1,10 @@ +global _start + +%include "header.inc" + + fld1 + fldpi + fyl2x + +%include "footer.inc" + diff --git a/tests/nasm/fyl2xp1.asm b/tests/nasm/fyl2xp1.asm new file mode 100644 index 00000000..5b4236e7 --- /dev/null +++ b/tests/nasm/fyl2xp1.asm @@ -0,0 +1,9 @@ +global _start + +%include "header.inc" + + fld1 + fldpi + fyl2xp1 + +%include "footer.inc" diff --git a/tests/nasm/indirect-call.asm b/tests/nasm/indirect-call.asm new file mode 100644 index 00000000..a2774779 --- /dev/null +++ b/tests/nasm/indirect-call.asm @@ -0,0 +1,14 @@ +global _start + +section .data + +%include "header.inc" + + mov eax, foo + call eax +foo: + xor eax, eax + ; clear stack (pushed eip is not the same between vm and gdb execution) + mov dword [esp], 0 + +%include "footer.inc" diff --git a/tests/nasm/indirect-jump.asm b/tests/nasm/indirect-jump.asm new file mode 100644 index 00000000..4d74eeb6 --- /dev/null +++ b/tests/nasm/indirect-jump.asm @@ -0,0 +1,12 @@ +global _start + +section .data + +%include "header.inc" + + mov eax, foo + jmp eax +foo: + xor eax, eax + +%include "footer.inc" diff --git a/tests/nasm/pop_esp2.asm b/tests/nasm/pop_esp2.asm new file mode 100644 index 00000000..24b5d601 --- /dev/null +++ b/tests/nasm/pop_esp2.asm @@ -0,0 +1,12 @@ +global _start + +section .data + align 16 + +%include "header.inc" + + ; pop esp encoded using 8F + mov esp, stack_top-16 + db 8Fh, 0C4h + +%include "footer.inc"