diff --git a/exe/ops/ops.exe b/exe/ops/ops.exe index 4743f225d..44632266f 100755 Binary files a/exe/ops/ops.exe and b/exe/ops/ops.exe differ 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);