Small fixes

This commit is contained in:
dingusdev 2024-09-27 21:37:32 -07:00
parent 11de987ea9
commit f1e6a2ce93
3 changed files with 49 additions and 30 deletions

View File

@ -16,3 +16,5 @@
#define OPCODESHIFTREC(op, __VA_ARGS__) template <field_direction isleft, field_rc rec > void dppc_interpreter::ppc_##op(uint32_t instr) { __VA_ARGS__ }
#define OPCODE601REC(op, __VA_ARGS__) template <field_601 for601, field_rc rec> void dppc_interpreter::ppc_##op(uint32_t instr) { __VA_ARGS__ }
#define OPCODEEXTSIGN(op, __VA_ARGS__) template <class T, field_rc rec> void dppc_interpreter::ppc_##op(uint32_t instr) { __VA_ARGS__ }
#define ppc_store_iresult_reg(reg, ppc_result) ppc_state.gpr[reg] = ppc_result
#define ppc_set_xer(entry) ppc_state.spr[SPR::XER] |= entry

View File

@ -232,20 +232,26 @@ OPCODEOVREC (subfme,
uint32_t grab_ca = !!(ppc_state.spr[SPR::XER] & XER::CA);
uint32_t ppc_result_d = ~ppc_result_a + grab_ca - 1;
if (ppc_result_a == 0xFFFFFFFFUL && !grab_ca)
ppc_unset_xer(XER::CA);
else
if (ppc_result_a == 0xFFFFFFFFUL && !grab_ca) {
ppc_unset_xer(XER::CA);
}
else {
ppc_set_xer(XER::CA);
if (ov) {
if (ppc_result_d == ppc_result_a && int32_t(ppc_result_d) > 0)
ppc_set_xer(XER::SO | XER::OV);
else
ppc_unset_xer(XER::OV);
}
if (rec)
ppc_changecrf0(ppc_result_d);
if (ov) {
if (ppc_result_d == ppc_result_a && int32_t(ppc_result_d) > 0) {
ppc_set_xer(XER::SO | XER::OV);
}
else {
ppc_unset_xer(XER::OV);
}
}
if (rec) {
ppc_changecrf0(ppc_result_d);
}
ppc_store_iresult_reg(reg_d, ppc_result_d);
)
@ -276,7 +282,7 @@ OPCODEOVREC (subfze,
}
ppc_store_iresult_reg(reg_d, ppc_result_d);
)
)
OPCODESHIFT (andirc,
ppc_grab_regssauimm(instr);
@ -442,16 +448,19 @@ OPCODEOVREC (divw,
ppc_result_d = 0; // tested on G4 in Mac OS X 10.4 and Open Firmware.
// ppc_result_d = (int32_t(ppc_result_a) < 0) ? -1 : 0; /* UNDOCUMENTED! */
if (ov)
if (ov) {
ppc_set_xer(XER::SO | XER::OV);
}
} else if (ppc_result_a == 0x80000000UL && ppc_result_b == 0xFFFFFFFFUL) {
}
else if (ppc_result_a == 0x80000000UL && ppc_result_b == 0xFFFFFFFFUL) {
ppc_result_d = 0; // tested on G4 in Mac OS X 10.4 and Open Firmware.
if (ov)
ppc_set_xer(XER::SO | XER::OV);
} else { // normal signed devision
}
else { // normal signed devision
ppc_result_d = int32_t(ppc_result_a) / int32_t(ppc_result_b);
if (ov)
@ -470,21 +479,27 @@ OPCODEOVREC (divwu,
if (!ppc_result_b) { // division by zero
if (ov)
if (ov) {
ppc_set_xer(XER::SO | XER::OV);
}
if (rec)
if (rec) {
ppc_state.cr |= XER::CA;
}
} else {
ppc_result_d = ppc_result_a / ppc_result_b;
if (ov)
if (ov) {
ppc_unset_xer(XER::OV);
}
if (rec)
}
}
if (rec) {
ppc_changecrf0(ppc_result_d);
}
ppc_store_iresult_reg(reg_d, ppc_result_d);
)
@ -496,13 +511,12 @@ OPCODESHIFTREC (shift,
ppc_result_a = 0;
}
else {
ppc_result_a = isleft ? (ppc_result_d << (ppc_result_b & 0x1F))
: (ppc_result_d >> (ppc_result_b & 0x1F));
}
if (rec)
ppc_result_a = (isleft ? (ppc_result_d << (ppc_result_b & 0x1F))
: (ppc_result_d >> (ppc_result_b & 0x1F)));
}
if (rec) {
ppc_changecrf0(ppc_result_a);
}
ppc_store_iresult_reg(reg_a, ppc_result_a);
)
@ -1007,10 +1021,12 @@ OPCODELKAA (bc,
cnd_ok = (br_bo & 0x10) | (!(ppc_state.cr & (0x80000000UL >> br_bi)) == !(br_bo & 0x08));
if (ctr_ok && cnd_ok) {
if (a)
if (a) {
ppc_next_instruction_address = br_bd;
else
}
else {
ppc_next_instruction_address = uint32_t(ppc_state.pc + br_bd);
}
exec_flags = EXEF_BRANCH;
}
@ -1391,7 +1407,8 @@ OPCODEMEM (stux,
uint32_t ea = ppc_result_a + ppc_result_b;
mmu_write_vmem<T>(ea, instr, ppc_result_d);
ppc_state.gpr[reg_a] = ea;
} else {
}
else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
)

View File

@ -117,7 +117,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
void dppc_interpreter::ppc_##op(uint32_t instr) { \
__VA_ARGS__ \
} \
template void dppc_interpreter::ppc_##op<ppc_and, RC0>(uint32_t instr) \
template void dppc_interpreter::ppc_##op<ppc_and, RC0>(uint32_t instr); \
template void dppc_interpreter::ppc_##op<ppc_andc, RC0>(uint32_t instr); \
template void dppc_interpreter::ppc_##op<ppc_eqv, RC0>(uint32_t instr); \
template void dppc_interpreter::ppc_##op<ppc_nand, RC0>(uint32_t instr); \