From 44b57e56c2d458dbf1a6746747be29cbdec3d6db Mon Sep 17 00:00:00 2001 From: Evan Martin Date: Sat, 11 May 2024 16:11:49 -0700 Subject: [PATCH] print negative numbers in fpu tests --- exe/ops/ops.exe | Bin 5120 -> 5120 bytes exe/ops/util.cc | 13 ++++++------- x86/src/ops/fpu.rs | 35 ++++++++++++++++++++++++++++++++++- x86/src/ops/table.rs | 7 +++++++ 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/exe/ops/ops.exe b/exe/ops/ops.exe index 4743f225d22bc215ef862e34d39c5cd6a41c144f..44632266f9e5aa17518495847d1ff9f5722dfc3b 100755 GIT binary patch delta 763 zcmZqBXwaC@z@p=&sy4CZ3#0PpO2(;7Y`d5k7+$ze7GYV+bMwH>2e)6|Jb3%!-J6ql zvUKp>e0Trl-5X_W$6QQ=b^RtgvNp#G`3TEv$!->vUJs5=9+kTc&2KpF%BZ|p zKlvW3In&F(lf~I)Z{EVTl!=jdaulb6^!#67E&oe@yqNw6%*S_5sw`1e@quLoVh@LQJ`Drf)#3Z=nCou_!*79M8Fv(b#sp6m;Zl%(`V(r+ zmlt<`qgb`TFJqP#W0B&cMJBmZ1)^e!=8KUU|lb$&I|4jA4^k^J+0_PrkQL0h4QK3W|U*P-1MX= ztC^ZvqFKG!5wnM8YUa-79p+2TUzxL8_*fKLthRV-p>7#rS!_Aka_T(kfH delta 628 zcmZqBXwaC@z;bSa3HQX7FO1xqD;cLUu`Oa^V0fWBS%hWjf)lMVNu|Nonh@MJN}?Q;Fc;QIf#>kkGXnA7k2gMXXr z|9}_Ue}NRR{4f3SVk%fIOBQ2>rlJGGi@DVWsa&!Z8A5P0%PE0 z9WDjwzdxa7eR*;FH<$@C>(u0QE?LGOlUup8WM;us{diG;#`>Rizk2J7H3-xGWOEs)j*{s2&F-&N*#ep zWf%)4^YUm(3n5f}fVcx@;Qh%#JSvQAlgoK58P81K$m7V^HTg4;9WYs!*ML!eavZM| z!CMOihdcwJ8ix diff --git a/exe/ops/util.cc b/exe/ops/util.cc index 770d8c0db..106f6d622 100644 --- a/exe/ops/util.cc +++ b/exe/ops/util.cc @@ -27,10 +27,9 @@ void print(uint32_t x) { void print(double f) { // To print a float, we multiply by 1000 and print as decimal. - // TODO: retrowin32 doesn't support the fpu op that "<" needs. - // bool neg = f < 0; - // if (f < 0) - // f = -f; + bool neg = f < 0; + if (f < 0) + f = -f; uint32_t x = (uint32_t)(f * 1000.0); char buf[64]; size_t i = sizeof(buf); @@ -48,9 +47,9 @@ void print(double f) { } } } - // if (neg) { - // buf[--i] = '-'; - // } + if (neg) { + buf[--i] = '-'; + } print(std::string_view(&buf[i], sizeof(buf) - i)); } diff --git a/x86/src/ops/fpu.rs b/x86/src/ops/fpu.rs index 64e73e2bd..5a412b52d 100644 --- a/x86/src/ops/fpu.rs +++ b/x86/src/ops/fpu.rs @@ -1,5 +1,5 @@ use super::helpers::*; -use crate::{fpu, x86::CPU}; +use crate::{fpu, registers::Flags, x86::CPU}; use iced_x86::{Instruction, Register}; use memory::{Extensions, Mem}; @@ -382,6 +382,32 @@ pub fn fucomp_st0_sti(cpu: &mut CPU, mem: Mem, instr: &Instruction) { // TODO: raise the invalid-arithmetic-operand exception when appropriate. } +pub fn fcomi_st0_sti(cpu: &mut CPU, _mem: Mem, instr: &Instruction) { + let x = *cpu.fpu.st0(); + let y = *cpu.fpu.get(instr.op1_register()); + //cpu.flags.set(Flags::PF, false); + if x > y { + cpu.flags.set(Flags::ZF, false); + cpu.flags.set(Flags::CF, false); + } else if x < y { + cpu.flags.set(Flags::ZF, false); + cpu.flags.set(Flags::CF, true); + } else { + cpu.flags.set(Flags::ZF, true); + cpu.flags.set(Flags::CF, false); + } +} + +pub fn fucomi_st0_sti(cpu: &mut CPU, mem: Mem, instr: &Instruction) { + fcomi_st0_sti(cpu, mem, instr); + // TODO: raise the invalid-arithmetic-operand exception when appropriate. +} + +pub fn fucomip_st0_sti(cpu: &mut CPU, mem: Mem, instr: &Instruction) { + fucomi_st0_sti(cpu, mem, instr); + cpu.fpu.pop(); +} + pub fn frndint(cpu: &mut CPU, _mem: Mem, _instr: &Instruction) { let x = cpu.fpu.st0(); *x = x.round(); @@ -403,3 +429,10 @@ pub fn fldcw_m2byte(cpu: &mut CPU, mem: Mem, instr: &Instruction) { // TODO: control word mem.get_pod::(x86_addr(cpu, instr)); } + +pub fn fcmovnbe_st0_sti(cpu: &mut CPU, _mem: Mem, instr: &Instruction) { + if !cpu.flags.contains(Flags::CF) && !cpu.flags.contains(Flags::ZF) { + let y = *cpu.fpu.get(instr.op1_register()); + *cpu.fpu.st0() = y; + } +} diff --git a/x86/src/ops/table.rs b/x86/src/ops/table.rs index c51a5ee3a..ed4fd1edb 100644 --- a/x86/src/ops/table.rs +++ b/x86/src/ops/table.rs @@ -400,12 +400,19 @@ pub unsafe fn init_op_tab() { OP_TAB[iced_x86::Code::Fcomp_m64fp as usize] = Some(ops::fcomp_m64fp); OP_TAB[iced_x86::Code::Fcomp_st0_sti as usize] = Some(ops::fcomp_st0_sti); OP_TAB[iced_x86::Code::Fucomp_st0_sti as usize] = Some(ops::fucomp_st0_sti); + OP_TAB[iced_x86::Code::Fcomi_st0_sti as usize] = Some(ops::fcomi_st0_sti); + OP_TAB[iced_x86::Code::Fucomi_st0_sti as usize] = Some(ops::fucomi_st0_sti); + OP_TAB[iced_x86::Code::Fucomip_st0_sti as usize] = Some(ops::fucomip_st0_sti); + OP_TAB[iced_x86::Code::Frndint as usize] = Some(ops::frndint); OP_TAB[iced_x86::Code::Fnstsw_AX as usize] = Some(ops::fnstsw_ax); OP_TAB[iced_x86::Code::Fnstcw_m2byte as usize] = Some(ops::fnstcw_m2byte); OP_TAB[iced_x86::Code::Fldcw_m2byte as usize] = Some(ops::fldcw_m2byte); OP_TAB[iced_x86::Code::Fclex as usize] = Some(ops::nop); OP_TAB[iced_x86::Code::Fnclex as usize] = Some(ops::nop); + + OP_TAB[iced_x86::Code::Fcmovnbe_st0_sti as usize] = Some(ops::fcmovnbe_st0_sti); + OP_TAB[iced_x86::Code::Wait as usize] = Some(ops::nop); OP_TAB[iced_x86::Code::Pushad as usize] = Some(ops::pushad);