ppcfpopcodes: Fix fcmpo/fcmpu.

It was always changing CR1 (starting at CR bit 4) instead of the CR selected by crfD.
Also, it was clearing all but the FL,FG,FE,FU bits of FPRF of FPSCR.
This commit is contained in:
joevt 2023-12-16 05:30:02 -08:00 committed by Maxim Poliakovski
parent 920c2024be
commit 7f229b0fe8
3 changed files with 8 additions and 13 deletions

View File

@ -192,7 +192,6 @@ extern uint32_t reg_a;
extern uint32_t reg_b;
extern uint32_t reg_c;
extern uint32_t xercon;
extern uint32_t cmp_c;
extern uint32_t crm;
extern uint32_t br_bo;
extern uint32_t br_bi;

View File

@ -937,9 +937,7 @@ void dppc_interpreter::ppc_mcrfs() {
void dppc_interpreter::ppc_fcmpo() {
ppc_grab_regsfpsab();
ppc_state.fpscr &= 0xFFFF0FFF;
cmp_c = 0;
crf_d = 4;
uint32_t cmp_c = 0;
if (std::isnan(db_test_a) || std::isnan(db_test_b)) {
cmp_c |= (1 << CRx_bit::CR_SO);
@ -954,7 +952,7 @@ void dppc_interpreter::ppc_fcmpo() {
cmp_c |= (1 << CRx_bit::CR_EQ);
}
ppc_state.fpscr = (cmp_c >> 16);
ppc_state.fpscr = (ppc_state.fpscr & 0xFFFF0FFF) | (cmp_c >> 16); // FL,FG,FE,FU
ppc_state.cr = ((ppc_state.cr & ~(0xF0000000 >> crf_d)) | ((cmp_c) >> crf_d));
//if (std::isnan(db_test_a) || std::isnan(db_test_b)) {
@ -965,8 +963,7 @@ void dppc_interpreter::ppc_fcmpo() {
void dppc_interpreter::ppc_fcmpu() {
ppc_grab_regsfpsab();
cmp_c = 0;
crf_d = 4;
uint32_t cmp_c = 0;
if (std::isnan(db_test_a) || std::isnan(db_test_b)) {
cmp_c |= (1 << CRx_bit::CR_SO);
@ -981,7 +978,7 @@ void dppc_interpreter::ppc_fcmpu() {
cmp_c |= (1 << CRx_bit::CR_EQ);
}
ppc_state.fpscr = (cmp_c >> 16);
ppc_state.fpscr = (ppc_state.fpscr & 0xFFFF0FFF) | (cmp_c >> 16); // FL,FG,FE,FU
ppc_state.cr = ((ppc_state.cr & ~(0xF0000000 >> crf_d)) | ((cmp_c) >> crf_d));
//if (std::isnan(db_test_a) || std::isnan(db_test_b)) {

View File

@ -36,7 +36,6 @@ uint32_t reg_a;
uint32_t reg_b;
uint32_t reg_c; // used only for floating point multiplication operations
uint32_t xercon;
uint32_t cmp_c;
uint32_t crm;
uint32_t uimm;
uint32_t grab_sr;
@ -1276,7 +1275,7 @@ void dppc_interpreter::ppc_cmp() {
int crf_d = (ppc_cur_instruction >> 21) & 0x1C;
ppc_grab_regssab();
xercon = (ppc_state.spr[SPR::XER] & 0x80000000UL) >> 3;
cmp_c = (((int32_t)ppc_result_a) == ((int32_t)ppc_result_b))
uint32_t cmp_c = (((int32_t)ppc_result_a) == ((int32_t)ppc_result_b))
? 0x20000000UL
: (((int32_t)ppc_result_a) > ((int32_t)ppc_result_b)) ? 0x40000000UL : 0x80000000UL;
ppc_state.cr = ((ppc_state.cr & ~(0xf0000000UL >> crf_d)) | ((cmp_c + xercon) >> crf_d));
@ -1293,7 +1292,7 @@ void dppc_interpreter::ppc_cmpi() {
int crf_d = (ppc_cur_instruction >> 21) & 0x1C;
ppc_grab_regsasimm();
xercon = (ppc_state.spr[SPR::XER] & 0x80000000UL) >> 3;
cmp_c = (((int32_t)ppc_result_a) == simm)
uint32_t cmp_c = (((int32_t)ppc_result_a) == simm)
? 0x20000000UL
: (((int32_t)ppc_result_a) > simm) ? 0x40000000UL : 0x80000000UL;
ppc_state.cr = ((ppc_state.cr & ~(0xf0000000UL >> crf_d)) | ((cmp_c + xercon) >> crf_d));
@ -1310,7 +1309,7 @@ void dppc_interpreter::ppc_cmpl() {
int crf_d = (ppc_cur_instruction >> 21) & 0x1C;
ppc_grab_regssab();
xercon = (ppc_state.spr[SPR::XER] & 0x80000000UL) >> 3;
cmp_c = (ppc_result_a == ppc_result_b)
uint32_t cmp_c = (ppc_result_a == ppc_result_b)
? 0x20000000UL
: (ppc_result_a > ppc_result_b) ? 0x40000000UL : 0x80000000UL;
ppc_state.cr = ((ppc_state.cr & ~(0xf0000000UL >> crf_d)) | ((cmp_c + xercon) >> crf_d));
@ -1327,7 +1326,7 @@ void dppc_interpreter::ppc_cmpli() {
int crf_d = (ppc_cur_instruction >> 21) & 0x1C;
ppc_grab_regssauimm();
xercon = (ppc_state.spr[SPR::XER] & 0x80000000UL) >> 3;
cmp_c = (ppc_result_a == uimm) ? 0x20000000UL
uint32_t cmp_c = (ppc_result_a == uimm) ? 0x20000000UL
: (ppc_result_a > uimm) ? 0x40000000UL : 0x80000000UL;
ppc_state.cr = ((ppc_state.cr & ~(0xf0000000UL >> crf_d)) | ((cmp_c + xercon) >> crf_d));
}