ppcfpopcodes: fneg fix.

fneg inverts the sign bit regardless of nan status.
This commit is contained in:
joevt 2024-11-27 04:31:36 -08:00 committed by dingusdev
parent b38b1731a0
commit d41287c320
2 changed files with 8 additions and 12 deletions

View File

@ -816,18 +816,11 @@ template <field_rc rec>
void dppc_interpreter::ppc_fneg() { void dppc_interpreter::ppc_fneg() {
ppc_grab_regsfpdb(ppc_cur_instruction); ppc_grab_regsfpdb(ppc_cur_instruction);
double ppc_dblresult64_d = -(GET_FPR(reg_b)); uint64_t ppc_result64_d = FPR_INT(reg_b) ^ 0x8000000000000000U;
if (std::isnan(GET_FPR(reg_b))) { ppc_store_fpresult_int(reg_d, ppc_result64_d);
ppc_dblresult64_d = std::numeric_limits<double>::quiet_NaN();
}
if (snan_single_check(reg_b)) { snan_single_check(reg_d);
uint64_t qnan = 0x7FFC000000000000;
ppc_store_fpresult_int(reg_d, qnan);
} else {
ppc_store_fpresult_flt(reg_d, ppc_dblresult64_d);
}
if (rec) if (rec)
ppc_update_cr1(); ppc_update_cr1();

View File

@ -153,6 +153,9 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#define GET_FPR(reg) \ #define GET_FPR(reg) \
ppc_state.fpr[(reg)].dbl64_r ppc_state.fpr[(reg)].dbl64_r
#define FPR_INT(reg)\
ppc_state.fpr[reg].int64_r
#define ppc_grab_regsfpdiab(opcode) \ #define ppc_grab_regsfpdiab(opcode) \
int reg_d = (opcode >> 21) & 31; \ int reg_d = (opcode >> 21) & 31; \
int reg_a = (opcode >> 16) & 31; \ int reg_a = (opcode >> 16) & 31; \