CPU: Implement more instructions in interpreter + various fixes
Some checks failed
Build check / build (push) Waiting to run
Generate translation template / generate-pot (push) Failing after 44s

All of the changes are verified against real hardware, except for the byte string instructions
This commit is contained in:
Exzap 2025-06-28 14:53:15 +02:00
parent 0a121c97c7
commit 7db2b77983
7 changed files with 281 additions and 87 deletions

View file

@ -41,7 +41,7 @@ static void PPCInterpreter_ADD(PPCInterpreter_t* hCPU, uint32 opcode)
static void PPCInterpreter_ADDO(PPCInterpreter_t* hCPU, uint32 opcode) static void PPCInterpreter_ADDO(PPCInterpreter_t* hCPU, uint32 opcode)
{ {
// untested (Don't Starve Giant Edition uses this instruction + BSO) // Don't Starve Giant Edition uses this instruction + BSO
PPC_OPC_TEMPL3_XO(); PPC_OPC_TEMPL3_XO();
uint32 result = hCPU->gpr[rA] + hCPU->gpr[rB]; uint32 result = hCPU->gpr[rA] + hCPU->gpr[rB];
PPCInterpreter_setXerOV(hCPU, checkAdditionOverflow(hCPU->gpr[rA], hCPU->gpr[rB], result)); PPCInterpreter_setXerOV(hCPU, checkAdditionOverflow(hCPU->gpr[rA], hCPU->gpr[rB], result));
@ -113,7 +113,6 @@ static void PPCInterpreter_ADDEO(PPCInterpreter_t* hCPU, uint32 opcode)
else else
hCPU->xer_ca = 0; hCPU->xer_ca = 0;
PPCInterpreter_setXerOV(hCPU, checkAdditionOverflow(a, b, hCPU->gpr[rD])); PPCInterpreter_setXerOV(hCPU, checkAdditionOverflow(a, b, hCPU->gpr[rD]));
// update CR
if (opHasRC()) if (opHasRC())
ppc_update_cr0(hCPU, hCPU->gpr[rD]); ppc_update_cr0(hCPU, hCPU->gpr[rD]);
PPCInterpreter_nextInstruction(hCPU); PPCInterpreter_nextInstruction(hCPU);
@ -130,7 +129,7 @@ static void PPCInterpreter_ADDI(PPCInterpreter_t* hCPU, uint32 opcode)
static void PPCInterpreter_ADDIC(PPCInterpreter_t* hCPU, uint32 opcode) static void PPCInterpreter_ADDIC(PPCInterpreter_t* hCPU, uint32 opcode)
{ {
int rD, rA; sint32 rD, rA;
uint32 imm; uint32 imm;
PPC_OPC_TEMPL_D_SImm(opcode, rD, rA, imm); PPC_OPC_TEMPL_D_SImm(opcode, rD, rA, imm);
uint32 a = hCPU->gpr[rA]; uint32 a = hCPU->gpr[rA];
@ -145,7 +144,7 @@ static void PPCInterpreter_ADDIC(PPCInterpreter_t* hCPU, uint32 opcode)
static void PPCInterpreter_ADDIC_(PPCInterpreter_t* hCPU, uint32 opcode) static void PPCInterpreter_ADDIC_(PPCInterpreter_t* hCPU, uint32 opcode)
{ {
int rD, rA; sint32 rD, rA;
uint32 imm; uint32 imm;
PPC_OPC_TEMPL_D_SImm(opcode, rD, rA, imm); PPC_OPC_TEMPL_D_SImm(opcode, rD, rA, imm);
uint32 a = hCPU->gpr[rA]; uint32 a = hCPU->gpr[rA];
@ -155,14 +154,13 @@ static void PPCInterpreter_ADDIC_(PPCInterpreter_t* hCPU, uint32 opcode)
hCPU->xer_ca = 1; hCPU->xer_ca = 1;
else else
hCPU->xer_ca = 0; hCPU->xer_ca = 0;
// update cr0 flags
ppc_update_cr0(hCPU, hCPU->gpr[rD]); ppc_update_cr0(hCPU, hCPU->gpr[rD]);
PPCInterpreter_nextInstruction(hCPU); PPCInterpreter_nextInstruction(hCPU);
} }
static void PPCInterpreter_ADDIS(PPCInterpreter_t* hCPU, uint32 opcode) static void PPCInterpreter_ADDIS(PPCInterpreter_t* hCPU, uint32 opcode)
{ {
int rD, rA; sint32 rD, rA;
uint32 imm; uint32 imm;
PPC_OPC_TEMPL_D_Shift16(opcode, rD, rA, imm); PPC_OPC_TEMPL_D_Shift16(opcode, rD, rA, imm);
hCPU->gpr[rD] = (rA ? hCPU->gpr[rA] : 0) + imm; hCPU->gpr[rD] = (rA ? hCPU->gpr[rA] : 0) + imm;
@ -185,6 +183,23 @@ static void PPCInterpreter_ADDZE(PPCInterpreter_t* hCPU, uint32 opcode)
PPCInterpreter_nextInstruction(hCPU); PPCInterpreter_nextInstruction(hCPU);
} }
static void PPCInterpreter_ADDZEO(PPCInterpreter_t* hCPU, uint32 opcode)
{
PPC_OPC_TEMPL3_XO();
PPC_ASSERT(rB == 0);
uint32 a = hCPU->gpr[rA];
uint32 ca = hCPU->xer_ca;
hCPU->gpr[rD] = a + ca;
PPCInterpreter_setXerOV(hCPU, checkAdditionOverflow(a, 0, hCPU->gpr[rD]));
if ((a == 0xffffffff) && ca)
hCPU->xer_ca = 1;
else
hCPU->xer_ca = 0;
if (opHasRC())
ppc_update_cr0(hCPU, hCPU->gpr[rD]);
PPCInterpreter_nextInstruction(hCPU);
}
static void PPCInterpreter_ADDME(PPCInterpreter_t* hCPU, uint32 opcode) static void PPCInterpreter_ADDME(PPCInterpreter_t* hCPU, uint32 opcode)
{ {
PPC_OPC_TEMPL3_XO(); PPC_OPC_TEMPL3_XO();
@ -201,6 +216,23 @@ static void PPCInterpreter_ADDME(PPCInterpreter_t* hCPU, uint32 opcode)
PPCInterpreter_nextInstruction(hCPU); PPCInterpreter_nextInstruction(hCPU);
} }
static void PPCInterpreter_ADDMEO(PPCInterpreter_t* hCPU, uint32 opcode)
{
PPC_OPC_TEMPL3_XO();
PPC_ASSERT(rB == 0);
uint32 a = hCPU->gpr[rA];
uint32 ca = hCPU->xer_ca;
hCPU->gpr[rD] = a + ca + 0xffffffff;
PPCInterpreter_setXerOV(hCPU, checkAdditionOverflow(a, 0xffffffff, hCPU->gpr[rD]));
if (a || ca)
hCPU->xer_ca = 1;
else
hCPU->xer_ca = 0;
if (opHasRC())
ppc_update_cr0(hCPU, hCPU->gpr[rD]);
PPCInterpreter_nextInstruction(hCPU);
}
static void PPCInterpreter_SUBF(PPCInterpreter_t* hCPU, uint32 opcode) static void PPCInterpreter_SUBF(PPCInterpreter_t* hCPU, uint32 opcode)
{ {
PPC_OPC_TEMPL3_XO(); PPC_OPC_TEMPL3_XO();
@ -260,7 +292,7 @@ static void PPCInterpreter_SUBFCO(PPCInterpreter_t* hCPU, uint32 opcode)
static void PPCInterpreter_SUBFIC(PPCInterpreter_t* hCPU, uint32 opcode) static void PPCInterpreter_SUBFIC(PPCInterpreter_t* hCPU, uint32 opcode)
{ {
int rD, rA; sint32 rD, rA;
uint32 imm; uint32 imm;
PPC_OPC_TEMPL_D_SImm(opcode, rD, rA, imm); PPC_OPC_TEMPL_D_SImm(opcode, rD, rA, imm);
uint32 a = hCPU->gpr[rA]; uint32 a = hCPU->gpr[rA];
@ -284,7 +316,6 @@ static void PPCInterpreter_SUBFE(PPCInterpreter_t* hCPU, uint32 opcode)
hCPU->xer_ca = 1; hCPU->xer_ca = 1;
else else
hCPU->xer_ca = 0; hCPU->xer_ca = 0;
// update cr0
if (opHasRC()) if (opHasRC())
ppc_update_cr0(hCPU, hCPU->gpr[rD]); ppc_update_cr0(hCPU, hCPU->gpr[rD]);
PPCInterpreter_nextInstruction(hCPU); PPCInterpreter_nextInstruction(hCPU);
@ -304,7 +335,6 @@ static void PPCInterpreter_SUBFEO(PPCInterpreter_t* hCPU, uint32 opcode)
else else
hCPU->xer_ca = 0; hCPU->xer_ca = 0;
PPCInterpreter_setXerOV(hCPU, checkAdditionOverflow(~a, b, result)); PPCInterpreter_setXerOV(hCPU, checkAdditionOverflow(~a, b, result));
// update cr0
if (opHasRC()) if (opHasRC())
ppc_update_cr0(hCPU, hCPU->gpr[rD]); ppc_update_cr0(hCPU, hCPU->gpr[rD]);
PPCInterpreter_nextInstruction(hCPU); PPCInterpreter_nextInstruction(hCPU);
@ -326,9 +356,25 @@ static void PPCInterpreter_SUBFZE(PPCInterpreter_t* hCPU, uint32 opcode)
PPCInterpreter_nextInstruction(hCPU); PPCInterpreter_nextInstruction(hCPU);
} }
static void PPCInterpreter_SUBFZEO(PPCInterpreter_t* hCPU, uint32 opcode)
{
PPC_OPC_TEMPL3_XO();
PPC_ASSERT(rB == 0);
uint32 a = hCPU->gpr[rA];
uint32 ca = hCPU->xer_ca;
hCPU->gpr[rD] = ~a + ca;
PPCInterpreter_setXerOV(hCPU, checkAdditionOverflow(~a, 0, hCPU->gpr[rD]));
if (a == 0 && ca)
hCPU->xer_ca = 1;
else
hCPU->xer_ca = 0;
if (opHasRC())
ppc_update_cr0(hCPU, hCPU->gpr[rD]);
PPCInterpreter_nextInstruction(hCPU);
}
static void PPCInterpreter_SUBFME(PPCInterpreter_t* hCPU, uint32 opcode) static void PPCInterpreter_SUBFME(PPCInterpreter_t* hCPU, uint32 opcode)
{ {
// untested
PPC_OPC_TEMPL3_XO(); PPC_OPC_TEMPL3_XO();
PPC_ASSERT(rB == 0); PPC_ASSERT(rB == 0);
uint32 a = hCPU->gpr[rA]; uint32 a = hCPU->gpr[rA];
@ -339,7 +385,24 @@ static void PPCInterpreter_SUBFME(PPCInterpreter_t* hCPU, uint32 opcode)
hCPU->xer_ca = 1; hCPU->xer_ca = 1;
else else
hCPU->xer_ca = 0; hCPU->xer_ca = 0;
// update cr0 if (opcode & PPC_OPC_RC)
ppc_update_cr0(hCPU, hCPU->gpr[rD]);
PPCInterpreter_nextInstruction(hCPU);
}
static void PPCInterpreter_SUBFMEO(PPCInterpreter_t* hCPU, uint32 opcode)
{
PPC_OPC_TEMPL3_XO();
PPC_ASSERT(rB == 0);
uint32 a = hCPU->gpr[rA];
uint32 ca = hCPU->xer_ca;
hCPU->gpr[rD] = ~a + 0xFFFFFFFF + ca;
PPCInterpreter_setXerOV(hCPU, checkAdditionOverflow(~a, 0xFFFFFFFF, hCPU->gpr[rD]));
// update xer carry
if (ppc_carry_3(~a, 0xFFFFFFFF, ca))
hCPU->xer_ca = 1;
else
hCPU->xer_ca = 0;
if (opcode & PPC_OPC_RC) if (opcode & PPC_OPC_RC)
ppc_update_cr0(hCPU, hCPU->gpr[rD]); ppc_update_cr0(hCPU, hCPU->gpr[rD]);
PPCInterpreter_nextInstruction(hCPU); PPCInterpreter_nextInstruction(hCPU);
@ -352,13 +415,8 @@ static void PPCInterpreter_MULHW_(PPCInterpreter_t* hCPU, uint32 opcode)
sint64 b = (sint32)hCPU->gpr[rB]; sint64 b = (sint32)hCPU->gpr[rB];
sint64 c = a * b; sint64 c = a * b;
hCPU->gpr[rD] = ((uint64)c) >> 32; hCPU->gpr[rD] = ((uint64)c) >> 32;
if (opcode & PPC_OPC_RC) { if (opHasRC())
// update cr0 flags
#ifdef CEMU_DEBUG_ASSERT
assert_dbg();
#endif
ppc_update_cr0(hCPU, hCPU->gpr[rD]); ppc_update_cr0(hCPU, hCPU->gpr[rD]);
}
PPCInterpreter_nextInstruction(hCPU); PPCInterpreter_nextInstruction(hCPU);
} }
@ -409,14 +467,14 @@ static void PPCInterpreter_MULLI(PPCInterpreter_t* hCPU, uint32 opcode)
static void PPCInterpreter_DIVW(PPCInterpreter_t* hCPU, uint32 opcode) static void PPCInterpreter_DIVW(PPCInterpreter_t* hCPU, uint32 opcode)
{ {
PPC_OPC_TEMPL3_XO(); PPC_OPC_TEMPL3_XO();
sint32 a = hCPU->gpr[rA]; sint32 a = (sint32)hCPU->gpr[rA];
sint32 b = hCPU->gpr[rB]; sint32 b = (sint32)hCPU->gpr[rB];
if (b == 0) if (b == 0)
{ hCPU->gpr[rD] = a < 0 ? 0xFFFFFFFF : 0;
cemuLog_logDebug(LogType::Force, "Error: Division by zero! [{:08x}]", (uint32)hCPU->instructionPointer); else if (a == 0x80000000 && b == 0xFFFFFFFF)
b++; hCPU->gpr[rD] = 0xFFFFFFFF;
} else
hCPU->gpr[rD] = a / b; hCPU->gpr[rD] = a / b;
if (opHasRC()) if (opHasRC())
ppc_update_cr0(hCPU, hCPU->gpr[rD]); ppc_update_cr0(hCPU, hCPU->gpr[rD]);
PPCInterpreter_nextInstruction(hCPU); PPCInterpreter_nextInstruction(hCPU);
@ -425,16 +483,23 @@ static void PPCInterpreter_DIVW(PPCInterpreter_t* hCPU, uint32 opcode)
static void PPCInterpreter_DIVWO(PPCInterpreter_t* hCPU, uint32 opcode) static void PPCInterpreter_DIVWO(PPCInterpreter_t* hCPU, uint32 opcode)
{ {
PPC_OPC_TEMPL3_XO(); PPC_OPC_TEMPL3_XO();
sint32 a = hCPU->gpr[rA]; sint32 a = (sint32)hCPU->gpr[rA];
sint32 b = hCPU->gpr[rB]; sint32 b = (sint32)hCPU->gpr[rB];
if (b == 0) if (b == 0)
{ {
PPCInterpreter_setXerOV(hCPU, true); PPCInterpreter_setXerOV(hCPU, true);
PPCInterpreter_nextInstruction(hCPU); hCPU->gpr[rD] = a < 0 ? 0xFFFFFFFF : 0;
return; }
else if(a == 0x80000000 && b == 0xFFFFFFFF)
{
PPCInterpreter_setXerOV(hCPU, true);
hCPU->gpr[rD] = 0xFFFFFFFF;
}
else
{
hCPU->gpr[rD] = a / b;
PPCInterpreter_setXerOV(hCPU, false);
} }
hCPU->gpr[rD] = a / b;
PPCInterpreter_setXerOV(hCPU, false);
if (opHasRC()) if (opHasRC())
ppc_update_cr0(hCPU, hCPU->gpr[rD]); ppc_update_cr0(hCPU, hCPU->gpr[rD]);
PPCInterpreter_nextInstruction(hCPU); PPCInterpreter_nextInstruction(hCPU);
@ -443,12 +508,14 @@ static void PPCInterpreter_DIVWO(PPCInterpreter_t* hCPU, uint32 opcode)
static void PPCInterpreter_DIVWU(PPCInterpreter_t* hCPU, uint32 opcode) static void PPCInterpreter_DIVWU(PPCInterpreter_t* hCPU, uint32 opcode)
{ {
PPC_OPC_TEMPL3_XO(); PPC_OPC_TEMPL3_XO();
if (hCPU->gpr[rB] == 0) uint32 a = hCPU->gpr[rA];
{ uint32 b = hCPU->gpr[rB];
PPCInterpreter_nextInstruction(hCPU); if (b == 0)
return; hCPU->gpr[rD] = 0;
} else if (a == 0x80000000 && b == 0xFFFFFFFF)
hCPU->gpr[rD] = hCPU->gpr[rA] / hCPU->gpr[rB]; hCPU->gpr[rD] = 0;
else
hCPU->gpr[rD] = a / b;
if (opHasRC()) if (opHasRC())
ppc_update_cr0(hCPU, hCPU->gpr[rD]); ppc_update_cr0(hCPU, hCPU->gpr[rD]);
PPCInterpreter_nextInstruction(hCPU); PPCInterpreter_nextInstruction(hCPU);
@ -457,14 +524,23 @@ static void PPCInterpreter_DIVWU(PPCInterpreter_t* hCPU, uint32 opcode)
static void PPCInterpreter_DIVWUO(PPCInterpreter_t* hCPU, uint32 opcode) static void PPCInterpreter_DIVWUO(PPCInterpreter_t* hCPU, uint32 opcode)
{ {
PPC_OPC_TEMPL3_XO(); PPC_OPC_TEMPL3_XO();
if (hCPU->gpr[rB] == 0) uint32 a = hCPU->gpr[rA];
uint32 b = hCPU->gpr[rB];
if (b == 0)
{ {
PPCInterpreter_setXerOV(hCPU, true); PPCInterpreter_setXerOV(hCPU, true);
PPCInterpreter_nextInstruction(hCPU); hCPU->gpr[rD] = 0;
return; }
else if(a == 0x80000000 && b == 0xFFFFFFFF)
{
PPCInterpreter_setXerOV(hCPU, false);
hCPU->gpr[rD] = 0;
}
else
{
hCPU->gpr[rD] = a / b;
PPCInterpreter_setXerOV(hCPU, false);
} }
hCPU->gpr[rD] = hCPU->gpr[rA] / hCPU->gpr[rB];
PPCInterpreter_setXerOV(hCPU, false);
if (opHasRC()) if (opHasRC())
ppc_update_cr0(hCPU, hCPU->gpr[rD]); ppc_update_cr0(hCPU, hCPU->gpr[rD]);
PPCInterpreter_nextInstruction(hCPU); PPCInterpreter_nextInstruction(hCPU);
@ -491,6 +567,13 @@ static void PPCInterpreter_CRANDC(PPCInterpreter_t* hCPU, uint32 opcode)
PPCInterpreter_nextInstruction(hCPU); PPCInterpreter_nextInstruction(hCPU);
} }
static void PPCInterpreter_CRNAND(PPCInterpreter_t* hCPU, uint32 opcode)
{
PPC_OPC_TEMPL_X_CR();
ppc_setCRBit(hCPU, crD, (ppc_getCRBit(hCPU, crA)&ppc_getCRBit(hCPU, crB)) ^ 1);
PPCInterpreter_nextInstruction(hCPU);
}
static void PPCInterpreter_CROR(PPCInterpreter_t* hCPU, uint32 opcode) static void PPCInterpreter_CROR(PPCInterpreter_t* hCPU, uint32 opcode)
{ {
PPC_OPC_TEMPL_X_CR(); PPC_OPC_TEMPL_X_CR();

View file

@ -428,9 +428,6 @@ public:
} }
}; };
uint32 testIP[100];
uint32 testIPC = 0;
template <typename ppcItpCtrl> template <typename ppcItpCtrl>
class PPCInterpreterContainer class PPCInterpreterContainer
{ {
@ -466,6 +463,10 @@ public:
case 1: // virtual HLE case 1: // virtual HLE
PPCInterpreter_virtualHLE(hCPU, opcode); PPCInterpreter_virtualHLE(hCPU, opcode);
break; break;
case 3:
cemuLog_logDebug(LogType::Force, "Unsupported TWI instruction executed at {:08x}", hCPU->instructionPointer);
PPCInterpreter_nextInstruction(hCPU);
break;
case 4: case 4:
switch (PPC_getBits(opcode, 30, 5)) switch (PPC_getBits(opcode, 30, 5))
{ {
@ -482,8 +483,9 @@ public:
PPCInterpreter_PS_CMPU1(hCPU, opcode); PPCInterpreter_PS_CMPU1(hCPU, opcode);
break; break;
default: default:
debug_printf("Unknown execute %04X as [4->0] at %08X\n", PPC_getBits(opcode, 25, 5), hCPU->instructionPointer); cemuLog_logDebug(LogType::Force, "Unknown execute {:04x} as [4->0] at {:08x}", PPC_getBits(opcode, 25, 5), hCPU->instructionPointer);
cemu_assert_unimplemented(); cemu_assert_unimplemented();
hCPU->instructionPointer += 4;
break; break;
} }
break; break;
@ -509,8 +511,9 @@ public:
PPCInterpreter_PS_ABS(hCPU, opcode); PPCInterpreter_PS_ABS(hCPU, opcode);
break; break;
default: default:
debug_printf("Unknown execute %04X as [4->8] at %08X\n", PPC_getBits(opcode, 25, 5), hCPU->instructionPointer); cemuLog_logDebug(LogType::Force, "Unknown execute {:04x} as [4->8] at {:08x}", PPC_getBits(opcode, 25, 5), hCPU->instructionPointer);
cemu_assert_unimplemented(); cemu_assert_unimplemented();
hCPU->instructionPointer += 4;
break; break;
} }
break; break;
@ -548,8 +551,9 @@ public:
PPCInterpreter_PS_MERGE11(hCPU, opcode); PPCInterpreter_PS_MERGE11(hCPU, opcode);
break; break;
default: default:
debug_printf("Unknown execute %04X as [4->16] at %08X\n", PPC_getBits(opcode, 25, 5), hCPU->instructionPointer); cemuLog_logDebug(LogType::Force, "Unknown execute {:04x} as [4->16] at {:08x}", PPC_getBits(opcode, 25, 5), hCPU->instructionPointer);
debugBreakpoint(); cemu_assert_unimplemented();
hCPU->instructionPointer += 4;
break; break;
} }
break; break;
@ -590,8 +594,9 @@ public:
PPCInterpreter_PS_NMADD(hCPU, opcode); PPCInterpreter_PS_NMADD(hCPU, opcode);
break; break;
default: default:
debug_printf("Unknown execute %04X as [4] at %08X\n", PPC_getBits(opcode, 30, 5), hCPU->instructionPointer); cemuLog_logDebug(LogType::Force, "Unknown execute {:04x} as [4] at {:08x}", PPC_getBits(opcode, 30, 5), hCPU->instructionPointer);
cemu_assert_unimplemented(); cemu_assert_unimplemented();
hCPU->instructionPointer += 4;
break; break;
} }
break; break;
@ -623,12 +628,15 @@ public:
PPCInterpreter_BCX(hCPU, opcode); PPCInterpreter_BCX(hCPU, opcode);
break; break;
case 17: case 17:
if (PPC_getBits(opcode, 30, 1) == 1) { if (PPC_getBits(opcode, 30, 1) == 1)
{
PPCInterpreter_SC(hCPU, opcode); PPCInterpreter_SC(hCPU, opcode);
} }
else { else
debug_printf("Unsupported Opcode [0x17 --> 0x0]\n"); {
cemuLog_logDebug(LogType::Force, "Unsupported Opcode [0x17 --> 0x0]");
cemu_assert_unimplemented(); cemu_assert_unimplemented();
hCPU->instructionPointer += 4;
} }
break; break;
case 18: case 18:
@ -658,6 +666,9 @@ public:
case 193: case 193:
PPCInterpreter_CRXOR(hCPU, opcode); PPCInterpreter_CRXOR(hCPU, opcode);
break; break;
case 225:
PPCInterpreter_CRNAND(hCPU, opcode);
break;
case 257: case 257:
PPCInterpreter_CRAND(hCPU, opcode); PPCInterpreter_CRAND(hCPU, opcode);
break; break;
@ -674,8 +685,9 @@ public:
PPCInterpreter_BCCTR(hCPU, opcode); PPCInterpreter_BCCTR(hCPU, opcode);
break; break;
default: default:
debug_printf("Unknown execute %04X as [19] at %08X\n", PPC_getBits(opcode, 30, 10), hCPU->instructionPointer); cemuLog_logDebug(LogType::Force, "Unknown execute {:04x} as [19] at {:08x}\n", PPC_getBits(opcode, 30, 10), hCPU->instructionPointer);
cemu_assert_unimplemented(); cemu_assert_unimplemented();
hCPU->instructionPointer += 4;
break; break;
} }
break; break;
@ -713,9 +725,6 @@ public:
PPCInterpreter_CMP(hCPU, opcode); PPCInterpreter_CMP(hCPU, opcode);
break; break;
case 4: case 4:
#ifdef CEMU_DEBUG_ASSERT
debug_printf("TW instruction executed at %08x\n", hCPU->instructionPointer);
#endif
PPCInterpreter_TW(hCPU, opcode); PPCInterpreter_TW(hCPU, opcode);
break; break;
case 8: case 8:
@ -895,6 +904,12 @@ public:
case 522: case 522:
PPCInterpreter_ADDCO(hCPU, opcode); PPCInterpreter_ADDCO(hCPU, opcode);
break; break;
case 523: // 11 | OE
PPCInterpreter_MULHWU_(hCPU, opcode); // OE is ignored
break;
case 533:
PPCInterpreter_LSWX(hCPU, opcode);
break;
case 534: case 534:
PPCInterpreter_LWBRX(hCPU, opcode); PPCInterpreter_LWBRX(hCPU, opcode);
break; break;
@ -913,6 +928,9 @@ public:
case 567: case 567:
PPCInterpreter_LFSUX(hCPU, opcode); PPCInterpreter_LFSUX(hCPU, opcode);
break; break;
case 587: // 75 | OE
PPCInterpreter_MULHW_(hCPU, opcode); // OE is ignored for MULHW
break;
case 595: case 595:
PPCInterpreter_MFSR(hCPU, opcode); PPCInterpreter_MFSR(hCPU, opcode);
break; break;
@ -943,15 +961,30 @@ public:
case 663: case 663:
PPCInterpreter_STFSX(hCPU, opcode); PPCInterpreter_STFSX(hCPU, opcode);
break; break;
case 661:
PPCInterpreter_STSWX(hCPU, opcode);
break;
case 695: case 695:
PPCInterpreter_STFSUX(hCPU, opcode); PPCInterpreter_STFSUX(hCPU, opcode);
break; break;
case 712: // 200 | OE
PPCInterpreter_SUBFZEO(hCPU, opcode);
break;
case 714: // 202 | OE
PPCInterpreter_ADDZEO(hCPU, opcode);
break;
case 725: case 725:
PPCInterpreter_STSWI(hCPU, opcode); PPCInterpreter_STSWI(hCPU, opcode);
break; break;
case 727: case 727:
PPCInterpreter_STFDX(hCPU, opcode); PPCInterpreter_STFDX(hCPU, opcode);
break; break;
case 744: // 232 | OE
PPCInterpreter_SUBFMEO(hCPU, opcode);
break;
case 746: // 234 | OE
PPCInterpreter_ADDMEO(hCPU, opcode);
break;
case 747: case 747:
PPCInterpreter_MULLWO(hCPU, opcode); PPCInterpreter_MULLWO(hCPU, opcode);
break; break;
@ -998,10 +1031,8 @@ public:
PPCInterpreter_DCBZ(hCPU, opcode); PPCInterpreter_DCBZ(hCPU, opcode);
break; break;
default: default:
debug_printf("Unknown execute %04X as [31] at %08X\n", PPC_getBits(opcode, 30, 10), hCPU->instructionPointer); cemuLog_logDebug(LogType::Force, "Unknown execute {:04x} as [31] at {:08x}\n", PPC_getBits(opcode, 30, 10), hCPU->instructionPointer);
#ifdef CEMU_DEBUG_ASSERT cemu_assert_unimplemented();
assert_dbg();
#endif
hCPU->instructionPointer += 4; hCPU->instructionPointer += 4;
break; break;
} }
@ -1084,7 +1115,7 @@ public:
case 57: case 57:
PPCInterpreter_PSQ_LU(hCPU, opcode); PPCInterpreter_PSQ_LU(hCPU, opcode);
break; break;
case 59: //Opcode category case 59: // opcode category
switch (PPC_getBits(opcode, 30, 5)) switch (PPC_getBits(opcode, 30, 5))
{ {
case 18: case 18:
@ -1115,8 +1146,9 @@ public:
PPCInterpreter_FNMADDS(hCPU, opcode); PPCInterpreter_FNMADDS(hCPU, opcode);
break; break;
default: default:
debug_printf("Unknown execute %04X as [59] at %08X\n", PPC_getBits(opcode, 30, 10), hCPU->instructionPointer); cemuLog_logDebug(LogType::Force, "Unknown execute {:04x} as [59] at {:08x}\n", PPC_getBits(opcode, 30, 10), hCPU->instructionPointer);
cemu_assert_unimplemented(); cemu_assert_unimplemented();
hCPU->instructionPointer += 4;
break; break;
} }
break; break;
@ -1195,18 +1227,19 @@ public:
case 583: case 583:
PPCInterpreter_MFFS(hCPU, opcode); PPCInterpreter_MFFS(hCPU, opcode);
break; break;
case 711: // IBM documentation has this wrong as 771? case 711:
PPCInterpreter_MTFSF(hCPU, opcode); PPCInterpreter_MTFSF(hCPU, opcode);
break; break;
default: default:
debug_printf("Unknown execute %04X as [63] at %08X\n", PPC_getBits(opcode, 30, 10), hCPU->instructionPointer); cemuLog_logDebug(LogType::Force, "Unknown execute {:04x} as [63] at {:08x}\n", PPC_getBits(opcode, 30, 10), hCPU->instructionPointer);
cemu_assert_unimplemented(); cemu_assert_unimplemented();
PPCInterpreter_nextInstruction(hCPU);
break; break;
} }
} }
break; break;
default: default:
debug_printf("Unknown execute %04X at %08X\n", PPC_getBits(opcode, 5, 6), (unsigned int)hCPU->instructionPointer); cemuLog_logDebug(LogType::Force, "Unknown execute {:04x} at {:08x}\n", PPC_getBits(opcode, 5, 6), (unsigned int)hCPU->instructionPointer);
cemu_assert_unimplemented(); cemu_assert_unimplemented();
} }
} }

View file

@ -31,7 +31,7 @@ static void PPCInterpreter_STW(PPCInterpreter_t* hCPU, uint32 Opcode)
static void PPCInterpreter_STWU(PPCInterpreter_t* hCPU, uint32 Opcode) static void PPCInterpreter_STWU(PPCInterpreter_t* hCPU, uint32 Opcode)
{ {
int rA, rS; sint32 rA, rS;
uint32 imm; uint32 imm;
PPC_OPC_TEMPL_D_SImm(Opcode, rS, rA, imm); PPC_OPC_TEMPL_D_SImm(Opcode, rS, rA, imm);
ppcItpCtrl::ppcMem_writeDataU32(hCPU, hCPU->gpr[rA] + imm, hCPU->gpr[rS]); ppcItpCtrl::ppcMem_writeDataU32(hCPU, hCPU->gpr[rA] + imm, hCPU->gpr[rS]);
@ -42,7 +42,7 @@ static void PPCInterpreter_STWU(PPCInterpreter_t* hCPU, uint32 Opcode)
static void PPCInterpreter_STWX(PPCInterpreter_t* hCPU, uint32 Opcode) static void PPCInterpreter_STWX(PPCInterpreter_t* hCPU, uint32 Opcode)
{ {
int rA, rS, rB; sint32 rA, rS, rB;
PPC_OPC_TEMPL_X(Opcode, rS, rA, rB); PPC_OPC_TEMPL_X(Opcode, rS, rA, rB);
ppcItpCtrl::ppcMem_writeDataU32(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], hCPU->gpr[rS]); ppcItpCtrl::ppcMem_writeDataU32(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], hCPU->gpr[rS]);
PPCInterpreter_nextInstruction(hCPU); PPCInterpreter_nextInstruction(hCPU);
@ -103,7 +103,7 @@ static void PPCInterpreter_STWCX(PPCInterpreter_t* hCPU, uint32 Opcode)
static void PPCInterpreter_STWUX(PPCInterpreter_t* hCPU, uint32 Opcode) static void PPCInterpreter_STWUX(PPCInterpreter_t* hCPU, uint32 Opcode)
{ {
int rA, rS, rB; sint32 rA, rS, rB;
PPC_OPC_TEMPL_X(Opcode, rS, rA, rB); PPC_OPC_TEMPL_X(Opcode, rS, rA, rB);
ppcItpCtrl::ppcMem_writeDataU32(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], hCPU->gpr[rS]); ppcItpCtrl::ppcMem_writeDataU32(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], hCPU->gpr[rS]);
if (rA) if (rA)
@ -113,7 +113,7 @@ static void PPCInterpreter_STWUX(PPCInterpreter_t* hCPU, uint32 Opcode)
static void PPCInterpreter_STWBRX(PPCInterpreter_t* hCPU, uint32 Opcode) static void PPCInterpreter_STWBRX(PPCInterpreter_t* hCPU, uint32 Opcode)
{ {
int rA, rS, rB; sint32 rA, rS, rB;
PPC_OPC_TEMPL_X(Opcode, rS, rA, rB); PPC_OPC_TEMPL_X(Opcode, rS, rA, rB);
ppcItpCtrl::ppcMem_writeDataU32(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], _swapEndianU32(hCPU->gpr[rS])); ppcItpCtrl::ppcMem_writeDataU32(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], _swapEndianU32(hCPU->gpr[rS]));
PPCInterpreter_nextInstruction(hCPU); PPCInterpreter_nextInstruction(hCPU);
@ -121,7 +121,7 @@ static void PPCInterpreter_STWBRX(PPCInterpreter_t* hCPU, uint32 Opcode)
static void PPCInterpreter_STMW(PPCInterpreter_t* hCPU, uint32 Opcode) static void PPCInterpreter_STMW(PPCInterpreter_t* hCPU, uint32 Opcode)
{ {
int rS, rA; sint32 rS, rA;
uint32 imm; uint32 imm;
PPC_OPC_TEMPL_D_SImm(Opcode, rS, rA, imm); PPC_OPC_TEMPL_D_SImm(Opcode, rS, rA, imm);
uint32 ea = (rA ? hCPU->gpr[rA] : 0) + imm; uint32 ea = (rA ? hCPU->gpr[rA] : 0) + imm;
@ -136,7 +136,7 @@ static void PPCInterpreter_STMW(PPCInterpreter_t* hCPU, uint32 Opcode)
static void PPCInterpreter_STH(PPCInterpreter_t* hCPU, uint32 Opcode) static void PPCInterpreter_STH(PPCInterpreter_t* hCPU, uint32 Opcode)
{ {
int rA, rS; sint32 rA, rS;
uint32 imm; uint32 imm;
PPC_OPC_TEMPL_D_SImm(Opcode, rS, rA, imm); PPC_OPC_TEMPL_D_SImm(Opcode, rS, rA, imm);
ppcItpCtrl::ppcMem_writeDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm, (uint16)hCPU->gpr[rS]); ppcItpCtrl::ppcMem_writeDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm, (uint16)hCPU->gpr[rS]);
@ -145,7 +145,7 @@ static void PPCInterpreter_STH(PPCInterpreter_t* hCPU, uint32 Opcode)
static void PPCInterpreter_STHU(PPCInterpreter_t* hCPU, uint32 Opcode) static void PPCInterpreter_STHU(PPCInterpreter_t* hCPU, uint32 Opcode)
{ {
int rA, rS; sint32 rA, rS;
uint32 imm; uint32 imm;
PPC_OPC_TEMPL_D_SImm(Opcode, rS, rA, imm); PPC_OPC_TEMPL_D_SImm(Opcode, rS, rA, imm);
ppcItpCtrl::ppcMem_writeDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm, (uint16)hCPU->gpr[rS]); ppcItpCtrl::ppcMem_writeDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm, (uint16)hCPU->gpr[rS]);
@ -156,7 +156,7 @@ static void PPCInterpreter_STHU(PPCInterpreter_t* hCPU, uint32 Opcode)
static void PPCInterpreter_STHX(PPCInterpreter_t* hCPU, uint32 Opcode) static void PPCInterpreter_STHX(PPCInterpreter_t* hCPU, uint32 Opcode)
{ {
int rA, rS, rB; sint32 rA, rS, rB;
PPC_OPC_TEMPL_X(Opcode, rS, rA, rB); PPC_OPC_TEMPL_X(Opcode, rS, rA, rB);
ppcItpCtrl::ppcMem_writeDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], (uint16)hCPU->gpr[rS]); ppcItpCtrl::ppcMem_writeDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], (uint16)hCPU->gpr[rS]);
PPCInterpreter_nextInstruction(hCPU); PPCInterpreter_nextInstruction(hCPU);
@ -164,7 +164,7 @@ static void PPCInterpreter_STHX(PPCInterpreter_t* hCPU, uint32 Opcode)
static void PPCInterpreter_STHUX(PPCInterpreter_t* hCPU, uint32 Opcode) static void PPCInterpreter_STHUX(PPCInterpreter_t* hCPU, uint32 Opcode)
{ {
int rA, rS, rB; sint32 rA, rS, rB;
PPC_OPC_TEMPL_X(Opcode, rS, rA, rB); PPC_OPC_TEMPL_X(Opcode, rS, rA, rB);
ppcItpCtrl::ppcMem_writeDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], (uint16)hCPU->gpr[rS]); ppcItpCtrl::ppcMem_writeDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], (uint16)hCPU->gpr[rS]);
if (rA) if (rA)
@ -174,7 +174,7 @@ static void PPCInterpreter_STHUX(PPCInterpreter_t* hCPU, uint32 Opcode)
static void PPCInterpreter_STHBRX(PPCInterpreter_t* hCPU, uint32 Opcode) static void PPCInterpreter_STHBRX(PPCInterpreter_t* hCPU, uint32 Opcode)
{ {
int rA, rS, rB; sint32 rA, rS, rB;
PPC_OPC_TEMPL_X(Opcode, rS, rA, rB); PPC_OPC_TEMPL_X(Opcode, rS, rA, rB);
ppcItpCtrl::ppcMem_writeDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], _swapEndianU16((uint16)hCPU->gpr[rS])); ppcItpCtrl::ppcMem_writeDataU16(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], _swapEndianU16((uint16)hCPU->gpr[rS]));
PPCInterpreter_nextInstruction(hCPU); PPCInterpreter_nextInstruction(hCPU);
@ -182,7 +182,7 @@ static void PPCInterpreter_STHBRX(PPCInterpreter_t* hCPU, uint32 Opcode)
static void PPCInterpreter_STB(PPCInterpreter_t* hCPU, uint32 Opcode) static void PPCInterpreter_STB(PPCInterpreter_t* hCPU, uint32 Opcode)
{ {
int rA, rS; sint32 rA, rS;
uint32 imm; uint32 imm;
PPC_OPC_TEMPL_D_SImm(Opcode, rS, rA, imm); PPC_OPC_TEMPL_D_SImm(Opcode, rS, rA, imm);
ppcItpCtrl::ppcMem_writeDataU8(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm, (uint8)hCPU->gpr[rS]); ppcItpCtrl::ppcMem_writeDataU8(hCPU, (rA ? hCPU->gpr[rA] : 0) + imm, (uint8)hCPU->gpr[rS]);
@ -191,7 +191,7 @@ static void PPCInterpreter_STB(PPCInterpreter_t* hCPU, uint32 Opcode)
static void PPCInterpreter_STBU(PPCInterpreter_t* hCPU, uint32 Opcode) static void PPCInterpreter_STBU(PPCInterpreter_t* hCPU, uint32 Opcode)
{ {
int rA, rS; sint32 rA, rS;
uint32 imm; uint32 imm;
PPC_OPC_TEMPL_D_SImm(Opcode, rS, rA, imm); PPC_OPC_TEMPL_D_SImm(Opcode, rS, rA, imm);
ppcItpCtrl::ppcMem_writeDataU8(hCPU, hCPU->gpr[rA] + imm, (uint8)hCPU->gpr[rS]); ppcItpCtrl::ppcMem_writeDataU8(hCPU, hCPU->gpr[rA] + imm, (uint8)hCPU->gpr[rS]);
@ -201,7 +201,7 @@ static void PPCInterpreter_STBU(PPCInterpreter_t* hCPU, uint32 Opcode)
static void PPCInterpreter_STBX(PPCInterpreter_t* hCPU, uint32 Opcode) static void PPCInterpreter_STBX(PPCInterpreter_t* hCPU, uint32 Opcode)
{ {
int rA, rS, rB; sint32 rA, rS, rB;
PPC_OPC_TEMPL_X(Opcode, rS, rA, rB); PPC_OPC_TEMPL_X(Opcode, rS, rA, rB);
ppcItpCtrl::ppcMem_writeDataU8(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], (uint8)hCPU->gpr[rS]); ppcItpCtrl::ppcMem_writeDataU8(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], (uint8)hCPU->gpr[rS]);
PPCInterpreter_nextInstruction(hCPU); PPCInterpreter_nextInstruction(hCPU);
@ -209,7 +209,7 @@ static void PPCInterpreter_STBX(PPCInterpreter_t* hCPU, uint32 Opcode)
static void PPCInterpreter_STBUX(PPCInterpreter_t* hCPU, uint32 Opcode) static void PPCInterpreter_STBUX(PPCInterpreter_t* hCPU, uint32 Opcode)
{ {
int rA, rS, rB; sint32 rA, rS, rB;
PPC_OPC_TEMPL_X(Opcode, rS, rA, rB); PPC_OPC_TEMPL_X(Opcode, rS, rA, rB);
ppcItpCtrl::ppcMem_writeDataU8(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], (uint8)hCPU->gpr[rS]); ppcItpCtrl::ppcMem_writeDataU8(hCPU, (rA ? hCPU->gpr[rA] : 0) + hCPU->gpr[rB], (uint8)hCPU->gpr[rS]);
if (rA) if (rA)
@ -219,7 +219,7 @@ static void PPCInterpreter_STBUX(PPCInterpreter_t* hCPU, uint32 Opcode)
static void PPCInterpreter_STSWI(PPCInterpreter_t* hCPU, uint32 Opcode) static void PPCInterpreter_STSWI(PPCInterpreter_t* hCPU, uint32 Opcode)
{ {
int rA, rS, nb; sint32 rA, rS, nb;
PPC_OPC_TEMPL_X(Opcode, rS, rA, nb); PPC_OPC_TEMPL_X(Opcode, rS, rA, nb);
if (nb == 0) nb = 32; if (nb == 0) nb = 32;
uint32 ea = rA ? hCPU->gpr[rA] : 0; uint32 ea = rA ? hCPU->gpr[rA] : 0;
@ -229,7 +229,39 @@ static void PPCInterpreter_STSWI(PPCInterpreter_t* hCPU, uint32 Opcode)
{ {
if (i == 0) if (i == 0)
{ {
r = hCPU->gpr[rS]; r = rS < 32 ? hCPU->gpr[rS] : 0; // what happens if rS is out of bounds?
rS++;
rS %= 32;
i = 4;
}
ppcItpCtrl::ppcMem_writeDataU8(hCPU, ea, (r >> 24));
r <<= 8;
ea++;
i--;
nb--;
}
PPCInterpreter_nextInstruction(hCPU);
}
static void PPCInterpreter_STSWX(PPCInterpreter_t* hCPU, uint32 Opcode)
{
sint32 rA, rS, rB;
PPC_OPC_TEMPL_X(Opcode, rS, rA, rB);
sint32 nb = hCPU->spr.XER&0x7F;
if (nb == 0)
{
PPCInterpreter_nextInstruction(hCPU);
return;
}
uint32 ea = rA ? hCPU->gpr[rA] : 0;
ea += hCPU->gpr[rB];
uint32 r = 0;
int i = 0;
while (nb > 0)
{
if (i == 0)
{
r = rS < 32 ? hCPU->gpr[rS] : 0; // what happens if rS is out of bounds?
rS++; rS++;
rS %= 32; rS %= 32;
i = 4; i = 4;
@ -460,7 +492,6 @@ static void PPCInterpreter_LSWI(PPCInterpreter_t* hCPU, uint32 Opcode)
PPC_OPC_TEMPL_X(Opcode, rD, rA, nb); PPC_OPC_TEMPL_X(Opcode, rD, rA, nb);
if (nb == 0) if (nb == 0)
nb = 32; nb = 32;
uint32 ea = rA ? hCPU->gpr[rA] : 0; uint32 ea = rA ? hCPU->gpr[rA] : 0;
uint32 r = 0; uint32 r = 0;
int i = 4; int i = 4;
@ -470,7 +501,8 @@ static void PPCInterpreter_LSWI(PPCInterpreter_t* hCPU, uint32 Opcode)
if (i == 0) if (i == 0)
{ {
i = 4; i = 4;
hCPU->gpr[rD] = r; if(rD < 32)
hCPU->gpr[rD] = r;
rD++; rD++;
rD %= 32; rD %= 32;
r = 0; r = 0;
@ -487,7 +519,52 @@ static void PPCInterpreter_LSWI(PPCInterpreter_t* hCPU, uint32 Opcode)
r <<= 8; r <<= 8;
i--; i--;
} }
hCPU->gpr[rD] = r; if(rD < 32)
hCPU->gpr[rD] = r;
PPCInterpreter_nextInstruction(hCPU);
}
static void PPCInterpreter_LSWX(PPCInterpreter_t* hCPU, uint32 Opcode)
{
sint32 rA, rD, rB;
PPC_OPC_TEMPL_X(Opcode, rD, rA, rB);
// byte count comes from XER
uint32 nb = (hCPU->spr.XER>>0)&0x7F;
if (nb == 0)
{
PPCInterpreter_nextInstruction(hCPU);
return; // no-op
}
uint32 ea = rA ? hCPU->gpr[rA] : 0;
ea += hCPU->gpr[rB];
uint32 r = 0;
int i = 4;
uint8 v;
while (nb>0)
{
if (i == 0)
{
i = 4;
if(rD < 32)
hCPU->gpr[rD] = r;
rD++;
rD %= 32;
r = 0;
}
v = ppcItpCtrl::ppcMem_readDataU8(hCPU, ea);
r <<= 8;
r |= v;
ea++;
i--;
nb--;
}
while (i)
{
r <<= 8;
i--;
}
if(rD < 32)
hCPU->gpr[rD] = r;
PPCInterpreter_nextInstruction(hCPU); PPCInterpreter_nextInstruction(hCPU);
} }

View file

@ -77,7 +77,8 @@ uint32 PPCInterpreter_getXER(PPCInterpreter_t* hCPU)
void PPCInterpreter_setXER(PPCInterpreter_t* hCPU, uint32 v) void PPCInterpreter_setXER(PPCInterpreter_t* hCPU, uint32 v)
{ {
hCPU->spr.XER = v; const uint32 XER_MASK = 0xE0FFFFFF; // some bits are masked out. Figure out which ones exactly
hCPU->spr.XER = v & XER_MASK;
hCPU->xer_ca = (v >> XER_BIT_CA) & 1; hCPU->xer_ca = (v >> XER_BIT_CA) & 1;
hCPU->xer_so = (v >> XER_BIT_SO) & 1; hCPU->xer_so = (v >> XER_BIT_SO) & 1;
hCPU->xer_ov = (v >> XER_BIT_OV) & 1; hCPU->xer_ov = (v >> XER_BIT_OV) & 1;

View file

@ -93,7 +93,6 @@ void PPCInterpreter_MTCRF(PPCInterpreter_t* hCPU, uint32 Opcode)
{ {
// frequently used by GCC compiled code (e.g. SM64 port) // frequently used by GCC compiled code (e.g. SM64 port)
// tested // tested
uint32 rS; uint32 rS;
uint32 crfMask; uint32 crfMask;
PPC_OPC_TEMPL_XFX(Opcode, rS, crfMask); PPC_OPC_TEMPL_XFX(Opcode, rS, crfMask);

View file

@ -68,6 +68,8 @@ static void PPCInterpreter_TW(PPCInterpreter_t* hCPU, uint32 opcode)
PPC_OPC_TEMPL_X(opcode, to, rA, rB); PPC_OPC_TEMPL_X(opcode, to, rA, rB);
cemu_assert_debug(to == 0); cemu_assert_debug(to == 0);
if(to != 0)
PPCInterpreter_nextInstruction(hCPU);
if (rA == DEBUGGER_BP_T_DEBUGGER) if (rA == DEBUGGER_BP_T_DEBUGGER)
debugger_enterTW(hCPU); debugger_enterTW(hCPU);

View file

@ -96,7 +96,6 @@ namespace coreinit
{ {
ppcDefineParamU32(screenIndex, 0); ppcDefineParamU32(screenIndex, 0);
cemu_assert(screenIndex < 2); cemu_assert(screenIndex < 2);
cemuLog_logDebug(LogType::Force, "OSScreenFlipBuffersEx {}", screenIndex);
LatteGPUState.osScreen.screen[screenIndex].flipRequestCount++; LatteGPUState.osScreen.screen[screenIndex].flipRequestCount++;
_updateCurrentDrawScreen(screenIndex); _updateCurrentDrawScreen(screenIndex);
osLib_returnFromFunction(hCPU, 0); osLib_returnFromFunction(hCPU, 0);