Start fixes

This commit is contained in:
dingusdev 2024-10-06 21:25:07 -07:00
parent eb67b6ded0
commit 31ad4b28ed
7 changed files with 67 additions and 44 deletions

View File

@ -42,7 +42,7 @@ uint32_t cs_code[] = {
0x80C30008, 0x7CA50114, 0x80E3000C, 0x7CA53114, 0x85030010, 0x7CA53914,
0x4200FFE0, 0x7CA54114, 0x70800002, 0x41E20010, 0xA0030004, 0x38630002,
0x7CA50114, 0x70800001, 0x41E20010, 0x88030004, 0x5400402E, 0x7CA50114,
0x7C650194, /* 0x4E800020 */ 0x00005AF0
0x7C650194, 0x4E800020
};
constexpr uint32_t test_size = 0x8000; // 0x7FFFFFFC is the max

View File

@ -222,7 +222,7 @@ void ppc_release_int() {
/** Opcode decoding functions. */
static void ppc_opcode16(uint32_t instr) {
static void ppc_opcode16(uint32_t subop, uint32_t instr) {
Opcode16Grabber[instr & 3](instr);
}
@ -289,8 +289,6 @@ template void ppc_opcode19<NOT601>(uint32_t);
template void ppc_opcode19<IS601>(uint32_t);
void ppc_opcode31(uint32_t instr) {
uint16_t subop_grab = instr & 0x7FFUL;
Opcode31Grabber[subop_grab](instr);
}
void ppc_opcode59(uint32_t instr) {
@ -311,7 +309,35 @@ void ppc_main_opcode(uint32_t instr) {
num_opcodes[instr]++;
#endif
#endif
OpcodeGrabber[(instr >> 26) & 0x3F](instr);
uint32_t opcode = (instr >> 26) & 63;
switch (opcode) {
case 16:
Opcode16Grabber[instr & 3](instr);
break;
case 18:
Opcode16Grabber[instr & 3](instr);
break;
case 19:
if (is_601)
ppc_opcode19<IS601>(instr);
else
ppc_opcode19<NOT601>(instr);
break;
case 31:
uint16_t subop_grab = instr & 0x7FFUL;
Opcode31Grabber[subop_grab](instr);
break;
case 59:
uint16_t subop_grab = instr & 0x7FFUL;
Opcode31Grabber[subop_grab](instr);
break;
case 63:
uint16_t subop_grab = instr & 0x7FFUL;
Opcode31Grabber[subop_grab](instr);
break;
default:
OpcodeGrabber[opcode](instr);
}
#ifdef CPU_PROFILING
uint32_t load_chk = (instr >> 26);

View File

@ -583,7 +583,7 @@ OPCODEREC (mtfsfi, 63, 134,
}
)
OPCODEREC (mtfsb0, 63, 70,
OPCODE31 (mtfsb0, 63, 70,
int crf_d = (instr >> 21) & 0x1F;
if (!crf_d || (crf_d > 2)) { // FEX and VX can't be explicitly cleared
ppc_state.fpscr &= ~(0x80000000UL >> crf_d);
@ -593,7 +593,7 @@ OPCODEREC (mtfsb0, 63, 70,
ppc_update_cr1();
)
OPCODEREC (mtfsb1, 63, 38,
OPCODE31 (mtfsb1, 63, 38,
ppc_grab_crfd(instr);
if (!crf_d || (crf_d > 2)) { // FEX and VX can't be explicitly set
ppc_state.fpscr |= (0x80000000UL >> crf_d);
@ -604,7 +604,7 @@ OPCODEREC (mtfsb1, 63, 38,
}
)
OPCODE (mcrfs, 63, 64,
OPCODE31 (mcrfs, 63, 64,
ppc_grab_crfds(instr);
ppc_state.cr = (
(ppc_state.cr & ~(0xF0000000UL >> crf_d)) |
@ -622,7 +622,7 @@ OPCODE (mcrfs, 63, 64,
// Floating Point Comparisons
OPCODE (fcmpo, 63, 32,
OPCODE31 (fcmpo, 63, 32,
ppc_grab_regsfpsab(instr);
uint32_t cmp_c = 0;

View File

@ -45,11 +45,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
template <field_direction isleft, field_rc rec> \
void ppc_##op(uint32_t instr);
#undef OPCODECARRY
#define OPCODECARRY(op, grabber, number, ...) \
template <field_carry carry, field_rc rec, field_ov ov> \
void ppc_##op(uint32_t instr);
#undef OPCODEOVREC
#define OPCODEOVREC(op, grabber, number, ...) \
template <field_rc rec, field_ov ov> \

View File

@ -15,7 +15,7 @@ OPCODEREC (addic, , 6,
ppc_store_iresult_reg(reg_d, ppc_result_d);
)
OPCODECARRY (add, 31, 10,
OPCODEREC (add, 31, 266,
ppc_grab_regsdab(instr);
uint32_t ppc_result_d = ppc_result_a + ppc_result_b;
@ -28,6 +28,18 @@ OPCODECARRY (add, 31, 10,
ppc_store_iresult_reg(reg_d, ppc_result_d);
)
OPCODEREC (addc, 31, 10,
ppc_grab_regsdab(instr);
uint32_t ppc_result_d = ppc_result_a + ppc_result_b;
ppc_carry(ppc_result_a, ppc_result_d);
if (ov)
ppc_setsoov(ppc_result_a, ~ppc_result_b, ppc_result_d);
if (rec)
ppc_changecrf0(ppc_result_d);
ppc_store_iresult_reg(reg_d, ppc_result_d);
)
OPCODEOVREC (adde, 31, 138,
ppc_grab_regsdab(instr);
uint32_t xer_ca = !!(ppc_state.spr[SPR::XER] & XER::CA);
@ -97,7 +109,21 @@ OPCODE (subfic, , 8,
ppc_store_iresult_reg(reg_d, ppc_result_d);
)
OPCODECARRY (subf, 31, 8,
OPCODEOVREC (subf, 31, 40,
ppc_grab_regsdab(instr);
uint32_t ppc_result_d = ppc_result_b - ppc_result_a;
if (carry)
ppc_carry_sub(ppc_result_a, ppc_result_b);
if (ov)
ppc_setsoov(ppc_result_b, ppc_result_a, ppc_result_d);
if (rec)
ppc_changecrf0(ppc_result_d);
ppc_store_iresult_reg(reg_d, ppc_result_d);
)
OPCODEOVREC (subfc, 31, 8,
ppc_grab_regsdab(instr);
uint32_t ppc_result_d = ppc_result_b - ppc_result_a;

View File

@ -63,21 +63,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
template void dppc_interpreter::ppc_##op<RIGHT0, RC1>(uint32_t instr); \
template void dppc_interpreter::ppc_##op<LEFT1, RC1>(uint32_t instr);
#undef OPCODECARRY
#define OPCODECARRY(op, grabber, number, ...) \
template <field_carry carry, field_rc rec, field_ov ov> \
void dppc_interpreter::ppc_##op(uint32_t instr) { \
__VA_ARGS__ \
} \
template void dppc_interpreter::ppc_##op<CARRY0, RC0, OV0>(uint32_t instr); \
template void dppc_interpreter::ppc_##op<CARRY0, RC1, OV0>(uint32_t instr); \
template void dppc_interpreter::ppc_##op<CARRY0, RC0, OV1>(uint32_t instr); \
template void dppc_interpreter::ppc_##op<CARRY0, RC1, OV1>(uint32_t instr); \
template void dppc_interpreter::ppc_##op<CARRY1, RC0, OV0>(uint32_t instr); \
template void dppc_interpreter::ppc_##op<CARRY1, RC1, OV0>(uint32_t instr); \
template void dppc_interpreter::ppc_##op<CARRY1, RC0, OV1>(uint32_t instr); \
template void dppc_interpreter::ppc_##op<CARRY1, RC1, OV1>(uint32_t instr);
#undef OPCODEOVREC
#define OPCODEOVREC(op, grabber, number, ...) \
template <field_rc rec, field_ov ov> \

View File

@ -49,17 +49,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
Opcode##grabber##Grabber[number + (1 << 9) ] = ppc_##op<RIGHT0, RC0>; \
Opcode##grabber##Grabber[number + (1 << 9) + 1] = ppc_##op<RIGHT0, RC1>; \
#undef OPCODECARRY
#define OPCODECARRY(op, grabber, number, ...) \
Opcode##grabber##Grabber[number ] = ppc_##op<CARRY0, RC0, OV0>; \
Opcode##grabber##Grabber[number + 1] = ppc_##op<CARRY0, RC1, OV0>; \
Opcode##grabber##Grabber[number + 2] = ppc_##op<CARRY0, RC0, OV1>; \
Opcode##grabber##Grabber[number + 3] = ppc_##op<CARRY0, RC1, OV1>; \
Opcode##grabber##Grabber[number + (1 << 10) ] = ppc_##op<CARRY1, RC0, OV0>; \
Opcode##grabber##Grabber[number + (1 << 10) + 1] = ppc_##op<CARRY1, RC1, OV0>; \
Opcode##grabber##Grabber[number + (1 << 10) + 2] = ppc_##op<CARRY1, RC0, OV1>; \
Opcode##grabber##Grabber[number + (1 << 10) + 3] = ppc_##op<CARRY1, RC1, OV1>;
#undef OPCODEOVREC
#define OPCODEOVREC(op, grabber, number, ...) \
Opcode##grabber##Grabber[number ] = ppc_##op<RC0, OV0>; \
@ -90,8 +79,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#undef OPCODERECF
#define OPCODERECF(op, grabber, number, ...) \
Opcode##grabber##Grabber[ number << 1 ] = ppc_##op<RC0>; \
Opcode##grabber##Grabber[(number << 1) + 1] = ppc_##op<RC1>; \
for (int i = 0; i < 2048; i += 32) { \
Opcode##grabber##Grabber[(number + i) << 1 ] = ppc_##op<RC0>; \
Opcode##grabber##Grabber[((number + i) << 1) + 1] = ppc_##op<RC1>; \
}
#undef POWEROPCODEREC
#define POWEROPCODEREC(op, grabber, number, ...) \