mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-02-06 19:29:56 +00:00
Tweak s*u(x) and l*u(x) instructions for 601
These are what the instructions are supposed to do according the 601 manual.
This commit is contained in:
parent
1c95619aa4
commit
d22f926a8a
@ -1027,17 +1027,24 @@ void dppc_interpreter::ppc_lfs(uint32_t opcode) {
|
|||||||
|
|
||||||
void dppc_interpreter::ppc_lfsu(uint32_t opcode) {
|
void dppc_interpreter::ppc_lfsu(uint32_t opcode) {
|
||||||
ppc_grab_regsfpdia(opcode);
|
ppc_grab_regsfpdia(opcode);
|
||||||
if (reg_a) {
|
|
||||||
uint32_t ea = int32_t(int16_t(opcode));
|
if (reg_a == 0) {
|
||||||
ea += (reg_a) ? val_reg_a : 0;
|
if (is_601) {
|
||||||
uint32_t result = mmu_read_vmem<uint32_t>(opcode, ea);
|
val_reg_a = 0;
|
||||||
ppc_state.fpr[reg_d].dbl64_r = *(float*)(&result);
|
|
||||||
ppc_state.gpr[reg_a] = ea;
|
|
||||||
} else {
|
} else {
|
||||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t ea = int32_t(int16_t(opcode));
|
||||||
|
ea += val_reg_a;
|
||||||
|
uint32_t result = mmu_read_vmem<uint32_t>(opcode, ea);
|
||||||
|
ppc_state.fpr[reg_d].dbl64_r = *(float*)(&result);
|
||||||
|
if (reg_a != 0) //accounting for the 601's skipping of updating Reg A
|
||||||
|
ppc_state.gpr[reg_a] = ea;
|
||||||
|
}
|
||||||
|
|
||||||
void dppc_interpreter::ppc_lfsx(uint32_t opcode) {
|
void dppc_interpreter::ppc_lfsx(uint32_t opcode) {
|
||||||
ppc_grab_regsfpdiab(opcode);
|
ppc_grab_regsfpdiab(opcode);
|
||||||
uint32_t ea = val_reg_b + (reg_a ? val_reg_a : 0);
|
uint32_t ea = val_reg_b + (reg_a ? val_reg_a : 0);
|
||||||
@ -1047,14 +1054,22 @@ void dppc_interpreter::ppc_lfsx(uint32_t opcode) {
|
|||||||
|
|
||||||
void dppc_interpreter::ppc_lfsux(uint32_t opcode) {
|
void dppc_interpreter::ppc_lfsux(uint32_t opcode) {
|
||||||
ppc_grab_regsfpdiab(opcode);
|
ppc_grab_regsfpdiab(opcode);
|
||||||
if (reg_a) {
|
|
||||||
|
if (reg_a == 0) {
|
||||||
|
if (is_601) {
|
||||||
|
val_reg_a = 0;
|
||||||
|
} else {
|
||||||
|
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t ea = val_reg_a + val_reg_b;
|
uint32_t ea = val_reg_a + val_reg_b;
|
||||||
uint32_t result = mmu_read_vmem<uint32_t>(opcode, ea);
|
uint32_t result = mmu_read_vmem<uint32_t>(opcode, ea);
|
||||||
ppc_state.fpr[reg_d].dbl64_r = *(float*)(&result);
|
ppc_state.fpr[reg_d].dbl64_r = *(float*)(&result);
|
||||||
|
|
||||||
|
if (reg_a != 0) // accounting for the 601's skipping of updating Reg A
|
||||||
ppc_state.gpr[reg_a] = ea;
|
ppc_state.gpr[reg_a] = ea;
|
||||||
} else {
|
|
||||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dppc_interpreter::ppc_lfd(uint32_t opcode) {
|
void dppc_interpreter::ppc_lfd(uint32_t opcode) {
|
||||||
@ -1067,15 +1082,23 @@ void dppc_interpreter::ppc_lfd(uint32_t opcode) {
|
|||||||
|
|
||||||
void dppc_interpreter::ppc_lfdu(uint32_t opcode) {
|
void dppc_interpreter::ppc_lfdu(uint32_t opcode) {
|
||||||
ppc_grab_regsfpdia(opcode);
|
ppc_grab_regsfpdia(opcode);
|
||||||
if (reg_a != 0) {
|
|
||||||
|
if (reg_a == 0) {
|
||||||
|
if (is_601) {
|
||||||
|
val_reg_a = 0;
|
||||||
|
} else {
|
||||||
|
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t ea = int32_t(int16_t(opcode));
|
uint32_t ea = int32_t(int16_t(opcode));
|
||||||
ea += val_reg_a;
|
ea += val_reg_a;
|
||||||
uint64_t ppc_result64_d = mmu_read_vmem<uint64_t>(opcode, ea);
|
uint64_t ppc_result64_d = mmu_read_vmem<uint64_t>(opcode, ea);
|
||||||
ppc_store_fpresult_int(reg_d, ppc_result64_d);
|
ppc_store_fpresult_int(reg_d, ppc_result64_d);
|
||||||
|
|
||||||
|
if (reg_a != 0) // accounting for the 601's skipping of updating Reg A
|
||||||
ppc_state.gpr[reg_a] = ea;
|
ppc_state.gpr[reg_a] = ea;
|
||||||
} else {
|
|
||||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dppc_interpreter::ppc_lfdx(uint32_t opcode) {
|
void dppc_interpreter::ppc_lfdx(uint32_t opcode) {
|
||||||
@ -1087,14 +1110,22 @@ void dppc_interpreter::ppc_lfdx(uint32_t opcode) {
|
|||||||
|
|
||||||
void dppc_interpreter::ppc_lfdux(uint32_t opcode) {
|
void dppc_interpreter::ppc_lfdux(uint32_t opcode) {
|
||||||
ppc_grab_regsfpdiab(opcode);
|
ppc_grab_regsfpdiab(opcode);
|
||||||
if (reg_a) {
|
|
||||||
|
if (reg_a == 0) {
|
||||||
|
if (is_601) {
|
||||||
|
val_reg_a = 0;
|
||||||
|
} else {
|
||||||
|
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t ea = val_reg_a + val_reg_b;
|
uint32_t ea = val_reg_a + val_reg_b;
|
||||||
uint64_t ppc_result64_d = mmu_read_vmem<uint64_t>(opcode, ea);
|
uint64_t ppc_result64_d = mmu_read_vmem<uint64_t>(opcode, ea);
|
||||||
ppc_store_fpresult_int(reg_d, ppc_result64_d);
|
ppc_store_fpresult_int(reg_d, ppc_result64_d);
|
||||||
|
|
||||||
|
if (reg_a != 0) // accounting for the 601's skipping of updating Reg A
|
||||||
ppc_state.gpr[reg_a] = ea;
|
ppc_state.gpr[reg_a] = ea;
|
||||||
} else {
|
|
||||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dppc_interpreter::ppc_stfs(uint32_t opcode) {
|
void dppc_interpreter::ppc_stfs(uint32_t opcode) {
|
||||||
@ -1107,15 +1138,21 @@ void dppc_interpreter::ppc_stfs(uint32_t opcode) {
|
|||||||
|
|
||||||
void dppc_interpreter::ppc_stfsu(uint32_t opcode) {
|
void dppc_interpreter::ppc_stfsu(uint32_t opcode) {
|
||||||
ppc_grab_regsfpsia(opcode);
|
ppc_grab_regsfpsia(opcode);
|
||||||
if (reg_a != 0) {
|
|
||||||
|
if (reg_a == 0) {
|
||||||
|
if (is_601) {
|
||||||
|
val_reg_a = 0;
|
||||||
|
} else {
|
||||||
|
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t ea = int32_t(int16_t(opcode));
|
uint32_t ea = int32_t(int16_t(opcode));
|
||||||
ea += val_reg_a;
|
ea += val_reg_a;
|
||||||
float result = float(ppc_state.fpr[reg_s].dbl64_r);
|
float result = float(ppc_state.fpr[reg_s].dbl64_r);
|
||||||
mmu_write_vmem<uint32_t>(opcode, ea, *(uint32_t*)(&result));
|
mmu_write_vmem<uint32_t>(opcode, ea, *(uint32_t*)(&result));
|
||||||
ppc_state.gpr[reg_a] = ea;
|
ppc_state.gpr[reg_a] = ea;
|
||||||
} else {
|
|
||||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dppc_interpreter::ppc_stfsx(uint32_t opcode) {
|
void dppc_interpreter::ppc_stfsx(uint32_t opcode) {
|
||||||
@ -1127,14 +1164,20 @@ void dppc_interpreter::ppc_stfsx(uint32_t opcode) {
|
|||||||
|
|
||||||
void dppc_interpreter::ppc_stfsux(uint32_t opcode) {
|
void dppc_interpreter::ppc_stfsux(uint32_t opcode) {
|
||||||
ppc_grab_regsfpsiab(opcode);
|
ppc_grab_regsfpsiab(opcode);
|
||||||
if (reg_a) {
|
|
||||||
|
if (reg_a == 0) {
|
||||||
|
if (is_601) {
|
||||||
|
val_reg_a = 0;
|
||||||
|
} else {
|
||||||
|
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t ea = val_reg_a + val_reg_b;
|
uint32_t ea = val_reg_a + val_reg_b;
|
||||||
float result = float(ppc_state.fpr[reg_s].dbl64_r);
|
float result = float(ppc_state.fpr[reg_s].dbl64_r);
|
||||||
mmu_write_vmem<uint32_t>(opcode, ea, *(uint32_t*)(&result));
|
mmu_write_vmem<uint32_t>(opcode, ea, *(uint32_t*)(&result));
|
||||||
ppc_state.gpr[reg_a] = ea;
|
ppc_state.gpr[reg_a] = ea;
|
||||||
} else {
|
|
||||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dppc_interpreter::ppc_stfd(uint32_t opcode) {
|
void dppc_interpreter::ppc_stfd(uint32_t opcode) {
|
||||||
@ -1146,14 +1189,20 @@ void dppc_interpreter::ppc_stfd(uint32_t opcode) {
|
|||||||
|
|
||||||
void dppc_interpreter::ppc_stfdu(uint32_t opcode) {
|
void dppc_interpreter::ppc_stfdu(uint32_t opcode) {
|
||||||
ppc_grab_regsfpsia(opcode);
|
ppc_grab_regsfpsia(opcode);
|
||||||
if (reg_a != 0) {
|
|
||||||
|
if (reg_a == 0) {
|
||||||
|
if (is_601) {
|
||||||
|
val_reg_a = 0;
|
||||||
|
} else {
|
||||||
|
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t ea = int32_t(int16_t(opcode));
|
uint32_t ea = int32_t(int16_t(opcode));
|
||||||
ea += val_reg_a;
|
ea += val_reg_a;
|
||||||
mmu_write_vmem<uint64_t>(opcode, ea, ppc_state.fpr[reg_s].int64_r);
|
mmu_write_vmem<uint64_t>(opcode, ea, ppc_state.fpr[reg_s].int64_r);
|
||||||
ppc_state.gpr[reg_a] = ea;
|
ppc_state.gpr[reg_a] = ea;
|
||||||
} else {
|
|
||||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dppc_interpreter::ppc_stfdx(uint32_t opcode) {
|
void dppc_interpreter::ppc_stfdx(uint32_t opcode) {
|
||||||
@ -1164,13 +1213,19 @@ void dppc_interpreter::ppc_stfdx(uint32_t opcode) {
|
|||||||
|
|
||||||
void dppc_interpreter::ppc_stfdux(uint32_t opcode) {
|
void dppc_interpreter::ppc_stfdux(uint32_t opcode) {
|
||||||
ppc_grab_regsfpsiab(opcode);
|
ppc_grab_regsfpsiab(opcode);
|
||||||
if (reg_a != 0) {
|
|
||||||
|
if (reg_a == 0) {
|
||||||
|
if (is_601) {
|
||||||
|
val_reg_a = 0;
|
||||||
|
} else {
|
||||||
|
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t ea = val_reg_a + val_reg_b;
|
uint32_t ea = val_reg_a + val_reg_b;
|
||||||
mmu_write_vmem<uint64_t>(opcode, ea, ppc_state.fpr[reg_s].int64_r);
|
mmu_write_vmem<uint64_t>(opcode, ea, ppc_state.fpr[reg_s].int64_r);
|
||||||
ppc_state.gpr[reg_a] = ea;
|
ppc_state.gpr[reg_a] = ea;
|
||||||
} else {
|
|
||||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dppc_interpreter::ppc_stfiwx(uint32_t opcode) {
|
void dppc_interpreter::ppc_stfiwx(uint32_t opcode) {
|
||||||
|
@ -1531,14 +1531,21 @@ void dppc_interpreter::ppc_stu(uint32_t opcode) {
|
|||||||
num_int_stores++;
|
num_int_stores++;
|
||||||
#endif
|
#endif
|
||||||
ppc_grab_regssa(opcode);
|
ppc_grab_regssa(opcode);
|
||||||
if (reg_a != 0) {
|
|
||||||
|
if (reg_a == 0) {
|
||||||
|
if (is_601) {
|
||||||
|
ppc_result_a = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t ea = int32_t(int16_t(opcode));
|
uint32_t ea = int32_t(int16_t(opcode));
|
||||||
ea += ppc_result_a;
|
ea += ppc_result_a;
|
||||||
mmu_write_vmem<T>(opcode, ea, ppc_result_d);
|
mmu_write_vmem<T>(opcode, ea, ppc_result_d);
|
||||||
ppc_state.gpr[reg_a] = ea;
|
ppc_state.gpr[reg_a] = ea;
|
||||||
} else {
|
|
||||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template void dppc_interpreter::ppc_stu<uint8_t>(uint32_t opcode);
|
template void dppc_interpreter::ppc_stu<uint8_t>(uint32_t opcode);
|
||||||
@ -1551,13 +1558,20 @@ void dppc_interpreter::ppc_stux(uint32_t opcode) {
|
|||||||
num_int_stores++;
|
num_int_stores++;
|
||||||
#endif
|
#endif
|
||||||
ppc_grab_regssab(opcode);
|
ppc_grab_regssab(opcode);
|
||||||
if (reg_a != 0) {
|
|
||||||
|
if (reg_a == 0) {
|
||||||
|
if (is_601) {
|
||||||
|
ppc_result_a = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t ea = ppc_result_a + ppc_result_b;
|
uint32_t ea = ppc_result_a + ppc_result_b;
|
||||||
mmu_write_vmem<T>(opcode, ea, ppc_result_d);
|
mmu_write_vmem<T>(opcode, ea, ppc_result_d);
|
||||||
ppc_state.gpr[reg_a] = ea;
|
ppc_state.gpr[reg_a] = ea;
|
||||||
} else {
|
|
||||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template void dppc_interpreter::ppc_stux<uint8_t>(uint32_t opcode);
|
template void dppc_interpreter::ppc_stux<uint8_t>(uint32_t opcode);
|
||||||
@ -1644,9 +1658,11 @@ void dppc_interpreter::ppc_lzu(uint32_t opcode) {
|
|||||||
if ((reg_a != reg_d) && reg_a != 0) {
|
if ((reg_a != reg_d) && reg_a != 0) {
|
||||||
ea += ppc_result_a;
|
ea += ppc_result_a;
|
||||||
uint32_t ppc_result_d = mmu_read_vmem<T>(opcode, ea);
|
uint32_t ppc_result_d = mmu_read_vmem<T>(opcode, ea);
|
||||||
uint32_t ppc_result_a = ea;
|
|
||||||
ppc_store_iresult_reg(reg_d, ppc_result_d);
|
ppc_store_iresult_reg(reg_d, ppc_result_d);
|
||||||
|
if (!(is_601 && (reg_a == 0))) {
|
||||||
|
uint32_t ppc_result_a = ea;
|
||||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||||
}
|
}
|
||||||
@ -1680,9 +1696,11 @@ void dppc_interpreter::ppc_lzux(uint32_t opcode) {
|
|||||||
if ((reg_a != reg_d) && reg_a != 0) {
|
if ((reg_a != reg_d) && reg_a != 0) {
|
||||||
uint32_t ea = ppc_result_a + ppc_result_b;
|
uint32_t ea = ppc_result_a + ppc_result_b;
|
||||||
uint32_t ppc_result_d = mmu_read_vmem<T>(opcode, ea);
|
uint32_t ppc_result_d = mmu_read_vmem<T>(opcode, ea);
|
||||||
ppc_result_a = ea;
|
|
||||||
ppc_store_iresult_reg(reg_d, ppc_result_d);
|
ppc_store_iresult_reg(reg_d, ppc_result_d);
|
||||||
|
if (!(is_601 && (reg_a == 0))) {
|
||||||
|
uint32_t ppc_result_a = ea;
|
||||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||||
}
|
}
|
||||||
@ -1715,6 +1733,10 @@ void dppc_interpreter::ppc_lhau(uint32_t opcode) {
|
|||||||
ppc_store_iresult_reg(reg_d, int32_t(val));
|
ppc_store_iresult_reg(reg_d, int32_t(val));
|
||||||
uint32_t ppc_result_a = ea;
|
uint32_t ppc_result_a = ea;
|
||||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||||
|
if (!(is_601 && (reg_a == 0))) {
|
||||||
|
uint32_t ppc_result_a = ea;
|
||||||
|
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||||
}
|
}
|
||||||
@ -1731,6 +1753,10 @@ void dppc_interpreter::ppc_lhaux(uint32_t opcode) {
|
|||||||
ppc_store_iresult_reg(reg_d, int32_t(val));
|
ppc_store_iresult_reg(reg_d, int32_t(val));
|
||||||
uint32_t ppc_result_a = ea;
|
uint32_t ppc_result_a = ea;
|
||||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||||
|
if (!(is_601 && (reg_a == 0))) {
|
||||||
|
uint32_t ppc_result_a = ea;
|
||||||
|
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user