From df7ff764045a4606a262be4bc1b8c7ea5a2c2875 Mon Sep 17 00:00:00 2001 From: joevt Date: Tue, 9 Apr 2024 01:37:20 -0700 Subject: [PATCH] poweropcodes: Fix doz. Calculate overflow first before calculating condition codes because the overflow condition is copied from XER. Fix OV calculation. Previously, it was using power_setsoov which I think is only for add and subtract operations. doz does a subtract but only if the result is supposed to be positive, therefore a negative result indicates an overflow. --- cpu/ppc/poweropcodes.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/cpu/ppc/poweropcodes.cpp b/cpu/ppc/poweropcodes.cpp index 293d709..9edaf99 100644 --- a/cpu/ppc/poweropcodes.cpp +++ b/cpu/ppc/poweropcodes.cpp @@ -175,13 +175,18 @@ template void dppc_interpreter::power_divs(); template void dppc_interpreter::power_doz() { ppc_grab_regsdab(ppc_cur_instruction); - uint32_t ppc_result_d = (int32_t(ppc_result_a) >= int32_t(ppc_result_b)) ? 0 : - ppc_result_b - ppc_result_a; + uint32_t ppc_result_d = (int32_t(ppc_result_a) < int32_t(ppc_result_b)) ? + ppc_result_b - ppc_result_a : 0; + if (ov) { + if (int32_t(ppc_result_d) < 0) { + ppc_state.spr[SPR::XER] |= XER::SO | XER::OV; + } else { + ppc_state.spr[SPR::XER] &= ~XER::OV; + } + } if (rec) ppc_changecrf0(ppc_result_d); - if (ov) - power_setsoov(ppc_result_a, ppc_result_b, ppc_result_d); ppc_store_iresult_reg(reg_d, ppc_result_d); }