More attempted fixes

This commit is contained in:
dingusdev 2024-09-15 18:29:59 -07:00
parent f5e2d3be48
commit f511005461
4 changed files with 117 additions and 60 deletions

View File

@ -34,19 +34,16 @@ void ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits) {
#endif
uint32_t cs_code[] = {
0x3863FFFC, 0x7C861671, 0x41820090, 0x70600002,
0x41E2001C, 0xA0030004, 0x3884FFFE, 0x38630002,
0x5486F0BF, 0x7CA50114, 0x41820070, 0x70C60003,
0x41820014, 0x7CC903A6, 0x84030004, 0x7CA50114,
0x4200FFF8, 0x5486E13F, 0x41820050, 0x80030004,
0x7CC903A6, 0x80C30008, 0x7CA50114, 0x80E3000C,
0x7CA53114, 0x85030010, 0x7CA53914, 0x42400028,
0x80030004, 0x7CA54114, 0x80C30008, 0x7CA50114,
0x80E3000C, 0x7CA53114, 0x85030010, 0x7CA53914,
0x4200FFE0, 0x7CA54114, 0x70800002, 0x41E20010,
0xA0030004, 0x38630002, 0x7CA50114, 0x70800001,
0x41E20010, 0x88030004, 0x5400402E, 0x7CA50114,
0x7C650194, 0x4E800020};
0x3863FFFC, 0x7C861671, 0x41820090, 0x70600002, 0x41E2001C, 0xA0030004,
0x3884FFFE, 0x38630002, 0x5486F0BF, 0x7CA50114, 0x41820070, 0x70C60003,
0x41820014, 0x7CC903A6, 0x84030004, 0x7CA50114, 0x4200FFF8, 0x5486E13F,
0x41820050, 0x80030004, 0x7CC903A6, 0x80C30008, 0x7CA50114, 0x80E3000C,
0x7CA53114, 0x85030010, 0x7CA53914, 0x42400028, 0x80030004, 0x7CA54114,
0x80C30008, 0x7CA50114, 0x80E3000C, 0x7CA53114, 0x85030010, 0x7CA53914,
0x4200FFE0, 0x7CA54114, 0x70800002, 0x41E20010, 0xA0030004, 0x38630002,
0x7CA50114, 0x70800001, 0x41E20010, 0x88030004, 0x5400402E, 0x7CA50114,
0x7C650194, 0x4E800020
};
constexpr uint32_t test_size = 0x8000; // 0x7FFFFFFC is the max
constexpr uint32_t test_samples = 200;

View File

@ -76,6 +76,8 @@ typedef struct struct_ppc_instr {
uint8_t arg4;
int32_t addr;
int32_t mask;
uint8_t main_op;
uint16_t sub_op;
union {
int32_t i_simm;
@ -424,6 +426,7 @@ void ppc_assert_int();
void ppc_release_int();
void decode_instr();
void exec_instr();
void initialize_ppc_opcode_tables(bool include_601);
extern double fp_return_double(uint32_t reg);

View File

@ -56,7 +56,6 @@ using namespace dppc_interpreter;
MemCtrlBase* mem_ctrl_instance = 0;
void (*ref_instr)();
SetPRS ppc_state;
SetInstr instr;
@ -233,80 +232,63 @@ void ppc_release_int() {
/** Opcode decoding functions. */
static void ppc_opcode16() {
ref_instr = SubOpcode16Grabber[ppc_cur_instruction & 3];
instr.sub_op = ppc_cur_instruction & 0x3;
ppc_grab_branch(ppc_cur_instruction);
}
static void ppc_opcode18() {
ref_instr = SubOpcode18Grabber[ppc_cur_instruction & 3];
instr.sub_op = ppc_cur_instruction & 0x3;
ppc_grab_branch(ppc_cur_instruction);
}
template<field_601 for601>
void ppc_opcode19() {
uint16_t subop_grab = ppc_cur_instruction & 0x7FF;
instr.sub_op = ppc_cur_instruction & 0x7FF;
switch (subop_grab) {
switch (instr.sub_op) {
case 0:
ref_instr = ppc_mcrf;
ppc_grab_regs_crfds(ppc_cur_instruction);
break;
case 32:
ref_instr = ppc_bclr<LK0>;
ppc_grab_branch_cond(ppc_cur_instruction);
break;
case 33:
ref_instr = ppc_bclr<LK1>;
ppc_grab_branch_cond(ppc_cur_instruction);
break;
case 66:
ref_instr = ppc_crnor;
ppc_grab_dab(ppc_cur_instruction);
break;
case 100:
ref_instr = ppc_rfi;
break;
case 258:
ref_instr = ppc_crandc;
ppc_grab_dab(ppc_cur_instruction);
break;
case 300:
ref_instr = ppc_isync;
break;
case 386:
ref_instr = ppc_crxor;
ppc_grab_dab(ppc_cur_instruction);
break;
case 450:
ref_instr = ppc_crnand;
ppc_grab_dab(ppc_cur_instruction);
break;
case 514:
ref_instr = ppc_crand;
ppc_grab_dab(ppc_cur_instruction);
break;
case 578:
ref_instr = ppc_creqv;
ppc_grab_dab(ppc_cur_instruction);
break;
case 834:
ref_instr = ppc_crorc;
ppc_grab_dab(ppc_cur_instruction);
break;
case 898:
ref_instr = ppc_cror;
ppc_grab_dab(ppc_cur_instruction);
break;
case 1056:
ref_instr = ppc_bcctr<LK0, for601>;
ppc_grab_branch_cond(ppc_cur_instruction);
break;
case 1057:
ref_instr = ppc_bcctr<LK1, for601>;
ppc_grab_branch_cond(ppc_cur_instruction);
break;
default:
ppc_illegalop();
}
}
@ -314,10 +296,9 @@ template void ppc_opcode19<NOT601>();
template void ppc_opcode19<IS601>();
static void ppc_opcode31() {
uint16_t subop_grab = ppc_cur_instruction & 0x7FFUL;
ref_instr = SubOpcode31Grabber[subop_grab];
instr.sub_op = ppc_cur_instruction & 0x7FFUL;
switch ((subop_grab >> 1)) {
switch ((instr.sub_op >> 1)) {
case 0:
case 32:
ppc_grab_crfd_regsab(ppc_cur_instruction);
@ -344,16 +325,14 @@ static void ppc_opcode31() {
}
static void ppc_opcode59() {
uint16_t subop_grab = ppc_cur_instruction & 0x3FUL;
ref_instr = SubOpcode59Grabber[subop_grab];
instr.sub_op = ppc_cur_instruction & 0x3FUL;
ppc_grab_regsfpdabc(ppc_cur_instruction);
}
static void ppc_opcode63() {
uint16_t subop_grab = ppc_cur_instruction & 0x7FFUL;
ref_instr = SubOpcode63Grabber[subop_grab];
instr.sub_op = ppc_cur_instruction & 0x7FFUL;
switch ((subop_grab >> 1)) {
switch ((instr.sub_op >> 1)) {
case 0:
case 32:
ppc_grab_regsfpsab(ppc_cur_instruction);
@ -376,10 +355,8 @@ static void ppc_opcode63() {
/* Dispatch using main opcode */
static void ppc_main_opcode() {
uint32_t main_op = (ppc_cur_instruction >> 26) & 0x3F;
ref_instr = OpcodeGrabber[main_op];
switch (main_op) {
switch (instr.main_op) {
case 3:
ppc_grab_twi(ppc_cur_instruction);
break;
@ -409,8 +386,8 @@ static void ppc_main_opcode() {
}
void decode_instr() {
uint32_t main_op = (ppc_cur_instruction >> 26) & 0x3F;
switch (main_op) {
instr.main_op = (ppc_cur_instruction >> 26) & 0x3F;
switch (instr.main_op) {
case 16:
ppc_opcode16();
break;
@ -445,6 +422,87 @@ void decode_instr() {
#endif
}
template <field_601 for601>
inline static void exec_op19() {
switch (instr.sub_op) {
case 0:
ppc_mcrf();
break;
case 32:
ppc_bclr<LK0>();
break;
case 33:
ppc_bclr<LK1>();
break;
case 66:
ppc_crnor();
break;
case 100:
ppc_rfi();
break;
case 258:
ppc_crandc();
break;
case 300:
ppc_isync();
break;
case 386:
ppc_crxor();
break;
case 450:
ppc_crnand();
break;
case 514:
ppc_crand();
break;
case 578:
ppc_creqv();
break;
case 834:
ppc_crorc();
break;
case 898:
ppc_cror();
break;
case 1056:
ppc_bcctr<LK0, for601>();
break;
case 1057:
ppc_bcctr<LK1, for601>();
break;
default:
ppc_illegalop();
}
}
void exec_instr() {
switch (instr.main_op) {
case 16:
SubOpcode16Grabber[instr.sub_op]();
break;
case 18:
SubOpcode18Grabber[instr.sub_op]();
break;
case 19:
if (is_601)
exec_op19<IS601>();
else
exec_op19<NOT601>();
break;
case 31:
SubOpcode31Grabber[instr.sub_op]();
break;
case 59:
SubOpcode59Grabber[instr.sub_op]();
break;
case 63:
SubOpcode63Grabber[instr.sub_op]();
break;
default:
OpcodeGrabber[instr.main_op]();
}
}
static long long cpu_now_ns() {
#ifdef __APPLE__
return ConvertHostTimeToNanos2(mach_absolute_time());
@ -504,7 +562,7 @@ static void ppc_exec_inner()
// interpret execution block
while (power_on && ppc_state.pc < eb_end) {
ref_instr();
exec_instr();
if (g_icycles++ >= max_cycles || exec_timer) {
max_cycles = process_events();
}
@ -560,7 +618,8 @@ void ppc_exec_single()
}
mmu_translate_imem(ppc_state.pc);
ref_instr();
decode_instr();
exec_instr();
g_icycles++;
process_events();
@ -596,7 +655,7 @@ static void ppc_exec_until_inner(const uint32_t goal_addr)
// interpret execution block
while (power_on && ppc_state.pc < eb_end) {
ref_instr();
exec_instr();
if (g_icycles++ >= max_cycles || exec_timer) {
max_cycles = process_events();
}
@ -630,7 +689,7 @@ static void ppc_exec_until_inner(const uint32_t goal_addr)
}
// outer interpreter loop
void ppc_exec_until(volatile uint32_t goal_addr)
void ppc_exec_until(uint32_t goal_addr)
{
if (setjmp(exc_env)) {
// process low-level exceptions
@ -668,7 +727,7 @@ static void ppc_exec_dbg_inner(const uint32_t start_addr, const uint32_t size)
// interpret execution block
while (power_on && (ppc_state.pc < start_addr || ppc_state.pc >= start_addr + size)
&& (ppc_state.pc < eb_end)) {
ref_instr();
exec_instr();
if (g_icycles++ >= max_cycles || exec_timer) {
max_cycles = process_events();
}
@ -699,7 +758,7 @@ static void ppc_exec_dbg_inner(const uint32_t start_addr, const uint32_t size)
}
// outer interpreter loop
void ppc_exec_dbg(volatile uint32_t start_addr, volatile uint32_t size)
void ppc_exec_dbg(uint32_t start_addr, uint32_t size)
{
if (setjmp(exc_env)) {
// process low-level exceptions

View File

@ -33,8 +33,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
using namespace std;
void (*ref_instr)();
int ntested; // number of tested instructions
int nfailed; // number of failed instructions
@ -50,7 +48,7 @@ static void xer_ov_test(string mnem, uint32_t opcode) {
ppc_state.spr[SPR::XER] = 0xFFFFFFFF;
ppc_cur_instruction = opcode;
decode_instr();
ref_instr();
exec_instr();
if (ppc_state.spr[SPR::XER] & 0x40000000UL) {
cout << "Invalid " << mnem << " emulation! XER[OV] should not be set." << endl;
nfailed++;
@ -155,9 +153,9 @@ static void read_test_data() {
ppc_state.cr = 0;
ppc_cur_instruction = opcode;
decode_instr();
ref_instr();
exec_instr();
ntested++;
@ -302,7 +300,7 @@ static void read_test_float_data() {
ppc_cur_instruction = opcode;
decode_instr();
ref_instr();
exec_instr();
ntested++;