Take 2 of removing ppc_cur_instruction

This commit is contained in:
dingusdev 2024-09-17 08:08:29 -07:00
parent 8c42685e26
commit 72308074da
9 changed files with 1052 additions and 1058 deletions

View File

@ -35,9 +35,9 @@ static inline uint32_t power_rot_mask(unsigned rot_mb, unsigned rot_me) {
}
template <field_rc rec, field_ov ov>
void dppc_interpreter::power_abs() {
void dppc_interpreter::power_abs(uint32_t instr) {
uint32_t ppc_result_d;
ppc_grab_regsda(ppc_cur_instruction);
ppc_grab_regsda(instr);
if (ppc_result_a == 0x80000000) {
ppc_result_d = ppc_result_a;
if (ov)
@ -54,14 +54,14 @@ void dppc_interpreter::power_abs() {
ppc_store_iresult_reg(reg_d, ppc_result_d);
}
template void dppc_interpreter::power_abs<RC0, OV0>();
template void dppc_interpreter::power_abs<RC0, OV1>();
template void dppc_interpreter::power_abs<RC1, OV0>();
template void dppc_interpreter::power_abs<RC1, OV1>();
template void dppc_interpreter::power_abs<RC0, OV0>(uint32_t);
template void dppc_interpreter::power_abs<RC0, OV1>(uint32_t);
template void dppc_interpreter::power_abs<RC1, OV0>(uint32_t);
template void dppc_interpreter::power_abs<RC1, OV1>(uint32_t);
void dppc_interpreter::power_clcs() {
void dppc_interpreter::power_clcs(uint32_t instr) {
uint32_t ppc_result_d;
ppc_grab_da(ppc_cur_instruction);
ppc_grab_da(instr);
switch (reg_a) {
case 12: //instruction cache line size
case 13: //data cache line size
@ -84,9 +84,9 @@ void dppc_interpreter::power_clcs() {
}
template <field_rc rec, field_ov ov>
void dppc_interpreter::power_div() {
void dppc_interpreter::power_div(uint32_t instr) {
uint32_t ppc_result_d;
ppc_grab_regsdab(ppc_cur_instruction);
ppc_grab_regsdab(instr);
int64_t dividend = (uint64_t(ppc_result_a) << 32) | ppc_state.spr[SPR::MQ];
int32_t divisor = ppc_result_b;
@ -123,16 +123,16 @@ void dppc_interpreter::power_div() {
ppc_state.spr[SPR::MQ] = remainder;
}
template void dppc_interpreter::power_div<RC0, OV0>();
template void dppc_interpreter::power_div<RC0, OV1>();
template void dppc_interpreter::power_div<RC1, OV0>();
template void dppc_interpreter::power_div<RC1, OV1>();
template void dppc_interpreter::power_div<RC0, OV0>(uint32_t);
template void dppc_interpreter::power_div<RC0, OV1>(uint32_t);
template void dppc_interpreter::power_div<RC1, OV0>(uint32_t);
template void dppc_interpreter::power_div<RC1, OV1>(uint32_t);
template <field_rc rec, field_ov ov>
void dppc_interpreter::power_divs() {
void dppc_interpreter::power_divs(uint32_t instr) {
uint32_t ppc_result_d;
int32_t remainder;
ppc_grab_regsdab(ppc_cur_instruction);
ppc_grab_regsdab(instr);
if (!ppc_result_b) { // handle the "anything / 0" case
ppc_result_d = -1;
@ -157,14 +157,14 @@ void dppc_interpreter::power_divs() {
ppc_state.spr[SPR::MQ] = remainder;
}
template void dppc_interpreter::power_divs<RC0, OV0>();
template void dppc_interpreter::power_divs<RC0, OV1>();
template void dppc_interpreter::power_divs<RC1, OV0>();
template void dppc_interpreter::power_divs<RC1, OV1>();
template void dppc_interpreter::power_divs<RC0, OV0>(uint32_t);
template void dppc_interpreter::power_divs<RC0, OV1>(uint32_t);
template void dppc_interpreter::power_divs<RC1, OV0>(uint32_t);
template void dppc_interpreter::power_divs<RC1, OV1>(uint32_t);
template <field_rc rec, field_ov ov>
void dppc_interpreter::power_doz() {
ppc_grab_regsdab(ppc_cur_instruction);
void dppc_interpreter::power_doz(uint32_t instr) {
ppc_grab_regsdab(instr);
uint32_t ppc_result_d = (int32_t(ppc_result_a) < int32_t(ppc_result_b)) ?
ppc_result_b - ppc_result_a : 0;
@ -181,14 +181,14 @@ void dppc_interpreter::power_doz() {
ppc_store_iresult_reg(reg_d, ppc_result_d);
}
template void dppc_interpreter::power_doz<RC0, OV0>();
template void dppc_interpreter::power_doz<RC0, OV1>();
template void dppc_interpreter::power_doz<RC1, OV0>();
template void dppc_interpreter::power_doz<RC1, OV1>();
template void dppc_interpreter::power_doz<RC0, OV0>(uint32_t);
template void dppc_interpreter::power_doz<RC0, OV1>(uint32_t);
template void dppc_interpreter::power_doz<RC1, OV0>(uint32_t);
template void dppc_interpreter::power_doz<RC1, OV1>(uint32_t);
void dppc_interpreter::power_dozi() {
void dppc_interpreter::power_dozi(uint32_t instr) {
uint32_t ppc_result_d;
ppc_grab_regsdasimm(ppc_cur_instruction);
ppc_grab_regsdasimm(instr);
if (((int32_t)ppc_result_a) > simm) {
ppc_result_d = 0;
} else {
@ -198,8 +198,8 @@ void dppc_interpreter::power_dozi() {
}
template <field_rc rec>
void dppc_interpreter::power_lscbx() {
ppc_grab_regsdab(ppc_cur_instruction);
void dppc_interpreter::power_lscbx(uint32_t instr) {
ppc_grab_regsdab(instr);
uint32_t ea = ppc_result_b + (reg_a ? ppc_result_a : 0);
uint32_t bytes_to_load = (ppc_state.spr[SPR::XER] & 0x7F);
@ -212,7 +212,7 @@ void dppc_interpreter::power_lscbx() {
uint8_t shift_amount = 24;
while (bytes_remaining > 0) {
uint8_t return_value = mmu_read_vmem<uint8_t>(ea);
uint8_t return_value = mmu_read_vmem<uint8_t>(ea, instr);
ppc_result_d |= return_value << shift_amount;
if (!shift_amount) {
@ -248,12 +248,12 @@ void dppc_interpreter::power_lscbx() {
}
}
template void dppc_interpreter::power_lscbx<RC0>();
template void dppc_interpreter::power_lscbx<RC1>();
template void dppc_interpreter::power_lscbx<RC0>(uint32_t);
template void dppc_interpreter::power_lscbx<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::power_maskg() {
ppc_grab_regssab(ppc_cur_instruction);
void dppc_interpreter::power_maskg(uint32_t instr) {
ppc_grab_regssab(instr);
uint32_t mask_start = ppc_result_d & 0x1F;
uint32_t mask_end = ppc_result_b & 0x1F;
uint32_t insert_mask = 0;
@ -276,12 +276,12 @@ void dppc_interpreter::power_maskg() {
ppc_store_iresult_reg(reg_a, ppc_result_a);
}
template void dppc_interpreter::power_maskg<RC0>();
template void dppc_interpreter::power_maskg<RC1>();
template void dppc_interpreter::power_maskg<RC0>(uint32_t);
template void dppc_interpreter::power_maskg<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::power_maskir() {
ppc_grab_regssab(ppc_cur_instruction);
void dppc_interpreter::power_maskir(uint32_t instr) {
ppc_grab_regssab(instr);
ppc_result_a = (ppc_result_a & ~ppc_result_b) | (ppc_result_d & ppc_result_b);
if (rec)
@ -290,12 +290,12 @@ void dppc_interpreter::power_maskir() {
ppc_store_iresult_reg(reg_a, ppc_result_a);
}
template void dppc_interpreter::power_maskir<RC0>();
template void dppc_interpreter::power_maskir<RC1>();
template void dppc_interpreter::power_maskir<RC0>(uint32_t);
template void dppc_interpreter::power_maskir<RC1>(uint32_t);
template <field_rc rec, field_ov ov>
void dppc_interpreter::power_mul() {
ppc_grab_regsdab(ppc_cur_instruction);
void dppc_interpreter::power_mul(uint32_t instr) {
ppc_grab_regsdab(instr);
int64_t product = int64_t(int32_t(ppc_result_a)) * int32_t(ppc_result_b);
uint32_t ppc_result_d = uint32_t(uint64_t(product) >> 32);
ppc_state.spr[SPR::MQ] = uint32_t(product);
@ -312,14 +312,14 @@ void dppc_interpreter::power_mul() {
ppc_store_iresult_reg(reg_d, ppc_result_d);
}
template void dppc_interpreter::power_mul<RC0, OV0>();
template void dppc_interpreter::power_mul<RC0, OV1>();
template void dppc_interpreter::power_mul<RC1, OV0>();
template void dppc_interpreter::power_mul<RC1, OV1>();
template void dppc_interpreter::power_mul<RC0, OV0>(uint32_t);
template void dppc_interpreter::power_mul<RC0, OV1>(uint32_t);
template void dppc_interpreter::power_mul<RC1, OV0>(uint32_t);
template void dppc_interpreter::power_mul<RC1, OV1>(uint32_t);
template <field_rc rec, field_ov ov>
void dppc_interpreter::power_nabs() {
ppc_grab_regsda(ppc_cur_instruction);
void dppc_interpreter::power_nabs(uint32_t instr) {
ppc_grab_regsda(instr);
uint32_t ppc_result_d = (int32_t(ppc_result_a) < 0) ? ppc_result_a : -ppc_result_a;
if (ov)
@ -330,15 +330,15 @@ void dppc_interpreter::power_nabs() {
ppc_store_iresult_reg(reg_d, ppc_result_d);
}
template void dppc_interpreter::power_nabs<RC0, OV0>();
template void dppc_interpreter::power_nabs<RC0, OV1>();
template void dppc_interpreter::power_nabs<RC1, OV0>();
template void dppc_interpreter::power_nabs<RC1, OV1>();
template void dppc_interpreter::power_nabs<RC0, OV0>(uint32_t);
template void dppc_interpreter::power_nabs<RC0, OV1>(uint32_t);
template void dppc_interpreter::power_nabs<RC1, OV0>(uint32_t);
template void dppc_interpreter::power_nabs<RC1, OV1>(uint32_t);
void dppc_interpreter::power_rlmi() {
ppc_grab_regssab(ppc_cur_instruction);
unsigned rot_mb = (ppc_cur_instruction >> 6) & 0x1F;
unsigned rot_me = (ppc_cur_instruction >> 1) & 0x1F;
void dppc_interpreter::power_rlmi(uint32_t instr) {
ppc_grab_regssab(instr);
unsigned rot_mb = (instr >> 6) & 0x1F;
unsigned rot_me = (instr >> 1) & 0x1F;
unsigned rot_sh = ppc_result_b & 0x1F;
uint32_t r = ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh)));
@ -346,15 +346,15 @@ void dppc_interpreter::power_rlmi() {
ppc_result_a = ((r & mask) | (ppc_result_a & ~mask));
if ((ppc_cur_instruction & 0x01) == 1)
if ((instr & 0x01) == 1)
ppc_changecrf0(ppc_result_a);
ppc_store_iresult_reg(reg_a, ppc_result_a);
}
template <field_rc rec>
void dppc_interpreter::power_rrib() {
ppc_grab_regssab(ppc_cur_instruction);
void dppc_interpreter::power_rrib(uint32_t instr) {
ppc_grab_regssab(instr);
unsigned rot_sh = ppc_result_b & 0x1F;
if (int32_t(ppc_result_d) < 0) {
@ -369,12 +369,12 @@ void dppc_interpreter::power_rrib() {
ppc_store_iresult_reg(reg_a, ppc_result_a);
}
template void dppc_interpreter::power_rrib<RC0>();
template void dppc_interpreter::power_rrib<RC1>();
template void dppc_interpreter::power_rrib<RC0>(uint32_t);
template void dppc_interpreter::power_rrib<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::power_sle() {
ppc_grab_regssab(ppc_cur_instruction);
void dppc_interpreter::power_sle(uint32_t instr) {
ppc_grab_regssab(instr);
unsigned rot_sh = ppc_result_b & 0x1F;
ppc_result_a = ppc_result_d << rot_sh;
@ -388,12 +388,12 @@ void dppc_interpreter::power_sle() {
ppc_store_iresult_reg(reg_a, ppc_result_a);
}
template void dppc_interpreter::power_sle<RC0>();
template void dppc_interpreter::power_sle<RC1>();
template void dppc_interpreter::power_sle<RC0>(uint32_t);
template void dppc_interpreter::power_sle<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::power_sleq() {
ppc_grab_regssab(ppc_cur_instruction);
void dppc_interpreter::power_sleq(uint32_t instr) {
ppc_grab_regssab(instr);
unsigned rot_sh = ppc_result_b & 0x1F;
uint32_t r = ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh)));
uint32_t mask = power_rot_mask(0, 31 - rot_sh);
@ -407,12 +407,12 @@ void dppc_interpreter::power_sleq() {
ppc_store_iresult_reg(reg_a, ppc_result_a);
}
template void dppc_interpreter::power_sleq<RC0>();
template void dppc_interpreter::power_sleq<RC1>();
template void dppc_interpreter::power_sleq<RC0>(uint32_t);
template void dppc_interpreter::power_sleq<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::power_sliq() {
ppc_grab_regssash(ppc_cur_instruction);
void dppc_interpreter::power_sliq(uint32_t instr) {
ppc_grab_regssash(instr);
ppc_result_a = ppc_result_d << rot_sh;
ppc_state.spr[SPR::MQ] = ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh)));
@ -423,12 +423,12 @@ void dppc_interpreter::power_sliq() {
ppc_store_iresult_reg(reg_a, ppc_result_a);
}
template void dppc_interpreter::power_sliq<RC0>();
template void dppc_interpreter::power_sliq<RC1>();
template void dppc_interpreter::power_sliq<RC0>(uint32_t);
template void dppc_interpreter::power_sliq<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::power_slliq() {
ppc_grab_regssash(ppc_cur_instruction);
void dppc_interpreter::power_slliq(uint32_t instr) {
ppc_grab_regssash(instr);
uint32_t r = ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh)));
uint32_t mask = power_rot_mask(0, 31 - rot_sh);
@ -441,12 +441,12 @@ void dppc_interpreter::power_slliq() {
ppc_store_iresult_reg(reg_a, ppc_result_a);
}
template void dppc_interpreter::power_slliq<RC0>();
template void dppc_interpreter::power_slliq<RC1>();
template void dppc_interpreter::power_slliq<RC0>(uint32_t);
template void dppc_interpreter::power_slliq<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::power_sllq() {
ppc_grab_regssab(ppc_cur_instruction);
void dppc_interpreter::power_sllq(uint32_t instr) {
ppc_grab_regssab(instr);
unsigned rot_sh = ppc_result_b & 0x1F;
if (ppc_result_b & 0x20) {
@ -461,12 +461,12 @@ void dppc_interpreter::power_sllq() {
ppc_store_iresult_reg(reg_a, ppc_result_a);
}
template void dppc_interpreter::power_sllq<RC0>();
template void dppc_interpreter::power_sllq<RC1>();
template void dppc_interpreter::power_sllq<RC0>(uint32_t);
template void dppc_interpreter::power_sllq<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::power_slq() {
ppc_grab_regssab(ppc_cur_instruction);
void dppc_interpreter::power_slq(uint32_t instr) {
ppc_grab_regssab(instr);
unsigned rot_sh = ppc_result_b & 0x1F;
if (ppc_result_b & 0x20) {
@ -482,12 +482,12 @@ void dppc_interpreter::power_slq() {
ppc_store_iresult_reg(reg_a, ppc_result_a);
}
template void dppc_interpreter::power_slq<RC0>();
template void dppc_interpreter::power_slq<RC1>();
template void dppc_interpreter::power_slq<RC0>(uint32_t);
template void dppc_interpreter::power_slq<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::power_sraiq() {
ppc_grab_regssash(ppc_cur_instruction);
void dppc_interpreter::power_sraiq(uint32_t instr) {
ppc_grab_regssash(instr);
uint32_t mask = (1 << rot_sh) - 1;
ppc_result_a = (int32_t)ppc_result_d >> rot_sh;
ppc_state.spr[SPR::MQ] = (ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh));
@ -504,12 +504,12 @@ void dppc_interpreter::power_sraiq() {
ppc_store_iresult_reg(reg_a, ppc_result_a);
}
template void dppc_interpreter::power_sraiq<RC0>();
template void dppc_interpreter::power_sraiq<RC1>();
template void dppc_interpreter::power_sraiq<RC0>(uint32_t);
template void dppc_interpreter::power_sraiq<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::power_sraq() {
ppc_grab_regssab(ppc_cur_instruction);
void dppc_interpreter::power_sraq(uint32_t instr) {
ppc_grab_regssab(instr);
unsigned rot_sh = ppc_result_b & 0x1F;
uint32_t mask = (ppc_result_b & 0x20) ? -1 : (1 << rot_sh) - 1;
ppc_result_a = (int32_t)ppc_result_d >> ((ppc_result_b & 0x20) ? 31 : rot_sh);
@ -529,12 +529,12 @@ void dppc_interpreter::power_sraq() {
ppc_store_iresult_reg(reg_a, ppc_result_a);
}
template void dppc_interpreter::power_sraq<RC0>();
template void dppc_interpreter::power_sraq<RC1>();
template void dppc_interpreter::power_sraq<RC0>(uint32_t);
template void dppc_interpreter::power_sraq<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::power_sre() {
ppc_grab_regssab(ppc_cur_instruction);
void dppc_interpreter::power_sre(uint32_t instr) {
ppc_grab_regssab(instr);
unsigned rot_sh = ppc_result_b & 0x1F;
ppc_result_a = ppc_result_d >> rot_sh;
@ -547,12 +547,12 @@ void dppc_interpreter::power_sre() {
ppc_store_iresult_reg(reg_a, ppc_result_a);
}
template void dppc_interpreter::power_sre<RC0>();
template void dppc_interpreter::power_sre<RC1>();
template void dppc_interpreter::power_sre<RC0>(uint32_t);
template void dppc_interpreter::power_sre<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::power_srea() {
ppc_grab_regssab(ppc_cur_instruction);
void dppc_interpreter::power_srea(uint32_t instr) {
ppc_grab_regssab(instr);
unsigned rot_sh = ppc_result_b & 0x1F;
ppc_result_a = (int32_t)ppc_result_d >> rot_sh;
uint32_t r = ((ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh)));
@ -571,12 +571,12 @@ void dppc_interpreter::power_srea() {
ppc_state.spr[SPR::MQ] = r;
}
template void dppc_interpreter::power_srea<RC0>();
template void dppc_interpreter::power_srea<RC1>();
template void dppc_interpreter::power_srea<RC0>(uint32_t);
template void dppc_interpreter::power_srea<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::power_sreq() {
ppc_grab_regssab(ppc_cur_instruction);
void dppc_interpreter::power_sreq(uint32_t instr) {
ppc_grab_regssab(instr);
unsigned rot_sh = ppc_result_b & 0x1F;
uint32_t mask = -1U >> rot_sh;
@ -589,12 +589,12 @@ void dppc_interpreter::power_sreq() {
ppc_store_iresult_reg(reg_a, ppc_result_a);
}
template void dppc_interpreter::power_sreq<RC0>();
template void dppc_interpreter::power_sreq<RC1>();
template void dppc_interpreter::power_sreq<RC0>(uint32_t);
template void dppc_interpreter::power_sreq<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::power_sriq() {
ppc_grab_regssash(ppc_cur_instruction);
void dppc_interpreter::power_sriq(uint32_t instr) {
ppc_grab_regssash(instr);
ppc_result_a = ppc_result_d >> rot_sh;
ppc_state.spr[SPR::MQ] = (ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh));
@ -604,12 +604,12 @@ void dppc_interpreter::power_sriq() {
ppc_store_iresult_reg(reg_a, ppc_result_a);
}
template void dppc_interpreter::power_sriq<RC0>();
template void dppc_interpreter::power_sriq<RC1>();
template void dppc_interpreter::power_sriq<RC0>(uint32_t);
template void dppc_interpreter::power_sriq<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::power_srliq() {
ppc_grab_regssash(ppc_cur_instruction);
void dppc_interpreter::power_srliq(uint32_t instr) {
ppc_grab_regssash(instr);
uint32_t r = (ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh));
unsigned mask = power_rot_mask(rot_sh, 31);
@ -622,12 +622,12 @@ void dppc_interpreter::power_srliq() {
ppc_store_iresult_reg(reg_a, ppc_result_a);
}
template void dppc_interpreter::power_srliq<RC0>();
template void dppc_interpreter::power_srliq<RC1>();
template void dppc_interpreter::power_srliq<RC0>(uint32_t);
template void dppc_interpreter::power_srliq<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::power_srlq() {
ppc_grab_regssab(ppc_cur_instruction);
void dppc_interpreter::power_srlq(uint32_t instr) {
ppc_grab_regssab(instr);
unsigned rot_sh = ppc_result_b & 0x1F;
uint32_t r = (ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh));
unsigned mask = power_rot_mask(rot_sh, 31);
@ -644,12 +644,12 @@ void dppc_interpreter::power_srlq() {
ppc_store_iresult_reg(reg_a, ppc_result_a);
}
template void dppc_interpreter::power_srlq<RC0>();
template void dppc_interpreter::power_srlq<RC1>();
template void dppc_interpreter::power_srlq<RC0>(uint32_t);
template void dppc_interpreter::power_srlq<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::power_srq() {
ppc_grab_regssab(ppc_cur_instruction);
void dppc_interpreter::power_srq(uint32_t instr) {
ppc_grab_regssab(instr);
unsigned rot_sh = ppc_result_b & 0x1F;
if (ppc_result_b & 0x20) {
@ -666,5 +666,5 @@ void dppc_interpreter::power_srq() {
ppc_store_iresult_reg(reg_a, ppc_result_a);
}
template void dppc_interpreter::power_srq<RC0>();
template void dppc_interpreter::power_srq<RC1>();
template void dppc_interpreter::power_srq<RC0>(uint32_t);
template void dppc_interpreter::power_srq<RC1>(uint32_t);

View File

@ -47,7 +47,7 @@ enum EXEC_MODE:uint32_t {
enum endian_switch { big_end = 0, little_end = 1 };
typedef void (*PPCOpcode)(void);
typedef void (*PPCOpcode)(uint32_t);
union FPR_storage {
double dbl64_r; // double floating-point representation
@ -328,12 +328,10 @@ extern bool is_601; // For PowerPC 601 Emulation
extern bool is_altivec; // For Altivec Emulation
extern bool is_64bit; // For PowerPC G5 Emulation
// Important Addressing Integers
extern uint32_t ppc_cur_instruction;
extern uint32_t ppc_next_instruction_address;
inline void ppc_set_cur_instruction(const uint8_t* ptr) {
ppc_cur_instruction = READ_DWORD_BE_A(ptr);
inline uint32_t ppc_set_cur_instruction(const uint8_t* ptr) {
return READ_DWORD_BE_A(ptr);
}
// Profiling Stats
@ -406,14 +404,6 @@ void ppc_fpu_off();
void ppc_assert_int();
void ppc_release_int();
//void ppc_opcode4();
void ppc_opcode16();
void ppc_opcode18();
template <field_601 for601> void ppc_opcode19();
void ppc_opcode31();
void ppc_opcode59();
void ppc_opcode63();
void initialize_ppc_opcode_tables(bool include_601);
extern double fp_return_double(uint32_t reg);
@ -426,8 +416,8 @@ void update_fpscr(uint32_t new_fpscr);
/* Exception handlers. */
void ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits);
[[noreturn]] void dbg_exception_handler(Except_Type exception_type, uint32_t srr1_bits);
void ppc_floating_point_exception();
void ppc_alignment_exception(uint32_t ea);
void ppc_floating_point_exception(uint32_t instr);
void ppc_alignment_exception(uint32_t ea, uint32_t instr);
// MEMORY DECLARATIONS
extern MemCtrlBase* mem_ctrl_instance;
@ -438,203 +428,203 @@ extern void do_ctx_sync(void);
// The functions used by the PowerPC processor
namespace dppc_interpreter {
template <field_lk l, field_601 for601> extern void ppc_bcctr();
template <field_lk l> extern void ppc_bclr();
extern void ppc_crand();
extern void ppc_crandc();
extern void ppc_creqv();
extern void ppc_crnand();
extern void ppc_crnor();
extern void ppc_cror();
extern void ppc_crorc();
extern void ppc_crxor();
extern void ppc_isync();
template <field_lk l, field_601 for601> extern void ppc_bcctr(uint32_t instr);
template <field_lk l> extern void ppc_bclr(uint32_t instr);
extern void ppc_crand(uint32_t instr);
extern void ppc_crandc(uint32_t instr);
extern void ppc_creqv(uint32_t instr);
extern void ppc_crnand(uint32_t instr);
extern void ppc_crnor(uint32_t instr);
extern void ppc_cror(uint32_t instr);
extern void ppc_crorc(uint32_t instr);
extern void ppc_crxor(uint32_t instr);
extern void ppc_isync(uint32_t instr);
template <logical_fun logical_op, field_rc rec> extern void ppc_logical();
template <logical_fun logical_op, field_rc rec> extern void ppc_logical(uint32_t instr);
template <field_carry carry, field_rc rec, field_ov ov> extern void ppc_add();
template <field_rc rec, field_ov ov> extern void ppc_adde();
template <field_rc rec, field_ov ov> extern void ppc_addme();
template <field_rc rec, field_ov ov> extern void ppc_addze();
extern void ppc_cmp();
extern void ppc_cmpl();
template <field_rc rec> extern void ppc_cntlzw();
extern void ppc_dcbf();
extern void ppc_dcbi();
extern void ppc_dcbst();
extern void ppc_dcbt();
extern void ppc_dcbtst();
extern void ppc_dcbz();
template <field_rc rec, field_ov ov> extern void ppc_divw();
template <field_rc rec, field_ov ov> extern void ppc_divwu();
extern void ppc_eciwx();
extern void ppc_ecowx();
extern void ppc_eieio();
template <class T, field_rc rec>extern void ppc_exts();
extern void ppc_icbi();
extern void ppc_mftb();
extern void ppc_lhaux();
extern void ppc_lhax();
extern void ppc_lhbrx();
extern void ppc_lwarx();
extern void ppc_lwbrx();
template <class T> extern void ppc_lzx();
template <class T> extern void ppc_lzux();
extern void ppc_mcrxr();
extern void ppc_mfcr();
template <field_rc rec> extern void ppc_mulhwu();
template <field_rc rec> extern void ppc_mulhw();
template <field_rc rec, field_ov ov> extern void ppc_mullw();
template <field_rc rec, field_ov ov> extern void ppc_neg();
template <field_direction shift, field_rc rec> extern void ppc_shift();
template <field_rc rec> extern void ppc_sraw();
template <field_rc rec> extern void ppc_srawi();
template <class T> extern void ppc_stx();
template <class T> extern void ppc_stux();
extern void ppc_stfiwx();
extern void ppc_sthbrx();
extern void ppc_stwcx();
extern void ppc_stwbrx();
template <field_carry carry, field_rc rec, field_ov ov> extern void ppc_subf();
template <field_rc rec, field_ov ov> extern void ppc_subfe();
template <field_rc rec, field_ov ov> extern void ppc_subfme();
template <field_rc rec, field_ov ov> extern void ppc_subfze();
extern void ppc_sync();
extern void ppc_tlbia();
extern void ppc_tlbie();
extern void ppc_tlbli();
extern void ppc_tlbld();
extern void ppc_tlbsync();
extern void ppc_tw();
template <field_carry carry, field_rc rec, field_ov ov> extern void ppc_add(uint32_t instr);
template <field_rc rec, field_ov ov> extern void ppc_adde(uint32_t instr);
template <field_rc rec, field_ov ov> extern void ppc_addme(uint32_t instr);
template <field_rc rec, field_ov ov> extern void ppc_addze(uint32_t instr);
extern void ppc_cmp(uint32_t instr);
extern void ppc_cmpl(uint32_t instr);
template <field_rc rec> extern void ppc_cntlzw(uint32_t instr);
extern void ppc_dcbf(uint32_t instr);
extern void ppc_dcbi(uint32_t instr);
extern void ppc_dcbst(uint32_t instr);
extern void ppc_dcbt(uint32_t instr);
extern void ppc_dcbtst(uint32_t instr);
extern void ppc_dcbz(uint32_t instr);
template <field_rc rec, field_ov ov> extern void ppc_divw(uint32_t instr);
template <field_rc rec, field_ov ov> extern void ppc_divwu(uint32_t instr);
extern void ppc_eciwx(uint32_t instr);
extern void ppc_ecowx(uint32_t instr);
extern void ppc_eieio(uint32_t instr);
template <class T, field_rc rec>extern void ppc_exts(uint32_t instr);
extern void ppc_icbi(uint32_t instr);
extern void ppc_mftb(uint32_t instr);
extern void ppc_lhaux(uint32_t instr);
extern void ppc_lhax(uint32_t instr);
extern void ppc_lhbrx(uint32_t instr);
extern void ppc_lwarx(uint32_t instr);
extern void ppc_lwbrx(uint32_t instr);
template <class T> extern void ppc_lzx(uint32_t instr);
template <class T> extern void ppc_lzux(uint32_t instr);
extern void ppc_mcrxr(uint32_t instr);
extern void ppc_mfcr(uint32_t instr);
template <field_rc rec> extern void ppc_mulhwu(uint32_t instr);
template <field_rc rec> extern void ppc_mulhw(uint32_t instr);
template <field_rc rec, field_ov ov> extern void ppc_mullw(uint32_t instr);
template <field_rc rec, field_ov ov> extern void ppc_neg(uint32_t instr);
template <field_direction shift, field_rc rec> extern void ppc_shift(uint32_t instr);
template <field_rc rec> extern void ppc_sraw(uint32_t instr);
template <field_rc rec> extern void ppc_srawi(uint32_t instr);
template <class T> extern void ppc_stx(uint32_t instr);
template <class T> extern void ppc_stux(uint32_t instr);
extern void ppc_stfiwx(uint32_t instr);
extern void ppc_sthbrx(uint32_t instr);
extern void ppc_stwcx(uint32_t instr);
extern void ppc_stwbrx(uint32_t instr);
template <field_carry carry, field_rc rec, field_ov ov> extern void ppc_subf(uint32_t instr);
template <field_rc rec, field_ov ov> extern void ppc_subfe(uint32_t instr);
template <field_rc rec, field_ov ov> extern void ppc_subfme(uint32_t instr);
template <field_rc rec, field_ov ov> extern void ppc_subfze(uint32_t instr);
extern void ppc_sync(uint32_t instr);
extern void ppc_tlbia(uint32_t instr);
extern void ppc_tlbie(uint32_t instr);
extern void ppc_tlbli(uint32_t instr);
extern void ppc_tlbld(uint32_t instr);
extern void ppc_tlbsync(uint32_t instr);
extern void ppc_tw(uint32_t instr);
extern void ppc_lswi();
extern void ppc_lswx();
extern void ppc_stswi();
extern void ppc_stswx();
extern void ppc_lswi(uint32_t instr);
extern void ppc_lswx(uint32_t instr);
extern void ppc_stswi(uint32_t instr);
extern void ppc_stswx(uint32_t instr);
extern void ppc_mfsr();
extern void ppc_mfsrin();
extern void ppc_mtsr();
extern void ppc_mtsrin();
extern void ppc_mfsr(uint32_t instr);
extern void ppc_mfsrin(uint32_t instr);
extern void ppc_mtsr(uint32_t instr);
extern void ppc_mtsrin(uint32_t instr);
extern void ppc_mcrf();
extern void ppc_mtcrf();
extern void ppc_mfmsr();
extern void ppc_mfspr();
extern void ppc_mtmsr();
extern void ppc_mtspr();
extern void ppc_mcrf(uint32_t instr);
extern void ppc_mtcrf(uint32_t instr);
extern void ppc_mfmsr(uint32_t instr);
extern void ppc_mfspr(uint32_t instr);
extern void ppc_mtmsr(uint32_t instr);
extern void ppc_mtspr(uint32_t instr);
template <field_rc rec> extern void ppc_mtfsb0();
template <field_rc rec> extern void ppc_mtfsb1();
extern void ppc_mcrfs();
template <field_rc rec> extern void ppc_fmr();
template <field_601 for601, field_rc rec> extern void ppc_mffs();
template <field_rc rec> extern void ppc_mtfsf();
template <field_rc rec> extern void ppc_mtfsfi();
template <field_rc rec> extern void ppc_mtfsb0(uint32_t instr);
template <field_rc rec> extern void ppc_mtfsb1(uint32_t instr);
extern void ppc_mcrfs(uint32_t instr);
template <field_rc rec> extern void ppc_fmr(uint32_t instr);
template <field_601 for601, field_rc rec> extern void ppc_mffs(uint32_t instr);
template <field_rc rec> extern void ppc_mtfsf(uint32_t instr);
template <field_rc rec> extern void ppc_mtfsfi(uint32_t instr);
template <field_shift shift> extern void ppc_addi();
template <field_rc rec> extern void ppc_addic();
template <field_shift shift> extern void ppc_andirc();
template <field_lk l, field_aa a> extern void ppc_b();
template <field_lk l, field_aa a> extern void ppc_bc();
extern void ppc_cmpi();
extern void ppc_cmpli();
template <class T> extern void ppc_lz();
template <class T> extern void ppc_lzu();
extern void ppc_lha();
extern void ppc_lhau();
extern void ppc_lmw();
extern void ppc_mulli();
template <field_shift shift> extern void ppc_ori();
extern void ppc_rfi();
extern void ppc_rlwimi();
extern void ppc_rlwinm();
extern void ppc_rlwnm();
extern void ppc_sc();
template <class T> extern void ppc_st();
template <class T> extern void ppc_stu();
extern void ppc_stmw();
extern void ppc_subfic();
extern void ppc_twi();
template <field_shift shift> extern void ppc_xori();
template <field_shift shift> extern void ppc_addi(uint32_t instr);
template <field_rc rec> extern void ppc_addic(uint32_t instr);
template <field_shift shift> extern void ppc_andirc(uint32_t instr);
template <field_lk l, field_aa a> extern void ppc_b(uint32_t instr);
template <field_lk l, field_aa a> extern void ppc_bc(uint32_t instr);
extern void ppc_cmpi(uint32_t instr);
extern void ppc_cmpli(uint32_t instr);
template <class T> extern void ppc_lz(uint32_t instr);
template <class T> extern void ppc_lzu(uint32_t instr);
extern void ppc_lha(uint32_t instr);
extern void ppc_lhau(uint32_t instr);
extern void ppc_lmw(uint32_t instr);
extern void ppc_mulli(uint32_t instr);
template <field_shift shift> extern void ppc_ori(uint32_t instr);
extern void ppc_rfi(uint32_t instr);
extern void ppc_rlwimi(uint32_t instr);
extern void ppc_rlwinm(uint32_t instr);
extern void ppc_rlwnm(uint32_t instr);
extern void ppc_sc(uint32_t instr);
template <class T> extern void ppc_st(uint32_t instr);
template <class T> extern void ppc_stu(uint32_t instr);
extern void ppc_stmw(uint32_t instr);
extern void ppc_subfic(uint32_t instr);
extern void ppc_twi(uint32_t instr);
template <field_shift shift> extern void ppc_xori(uint32_t instr);
extern void ppc_lfs();
extern void ppc_lfsu();
extern void ppc_lfsx();
extern void ppc_lfsux();
extern void ppc_lfd();
extern void ppc_lfdu();
extern void ppc_lfdx();
extern void ppc_lfdux();
extern void ppc_stfs();
extern void ppc_stfsu();
extern void ppc_stfsx();
extern void ppc_stfsux();
extern void ppc_stfd();
extern void ppc_stfdu();
extern void ppc_stfdx();
extern void ppc_stfdux();
extern void ppc_lfs(uint32_t instr);
extern void ppc_lfsu(uint32_t instr);
extern void ppc_lfsx(uint32_t instr);
extern void ppc_lfsux(uint32_t instr);
extern void ppc_lfd(uint32_t instr);
extern void ppc_lfdu(uint32_t instr);
extern void ppc_lfdx(uint32_t instr);
extern void ppc_lfdux(uint32_t instr);
extern void ppc_stfs(uint32_t instr);
extern void ppc_stfsu(uint32_t instr);
extern void ppc_stfsx(uint32_t instr);
extern void ppc_stfsux(uint32_t instr);
extern void ppc_stfd(uint32_t instr);
extern void ppc_stfdu(uint32_t instr);
extern void ppc_stfdx(uint32_t instr);
extern void ppc_stfdux(uint32_t instr);
template <field_rc rec> extern void ppc_fadd();
template <field_rc rec> extern void ppc_fsub();
template <field_rc rec> extern void ppc_fmul();
template <field_rc rec> extern void ppc_fdiv();
template <field_rc rec> extern void ppc_fadds();
template <field_rc rec> extern void ppc_fsubs();
template <field_rc rec> extern void ppc_fmuls();
template <field_rc rec> extern void ppc_fdivs();
template <field_rc rec> extern void ppc_fmadd();
template <field_rc rec> extern void ppc_fmsub();
template <field_rc rec> extern void ppc_fnmadd();
template <field_rc rec> extern void ppc_fnmsub();
template <field_rc rec> extern void ppc_fmadds();
template <field_rc rec> extern void ppc_fmsubs();
template <field_rc rec> extern void ppc_fnmadds();
template <field_rc rec> extern void ppc_fnmsubs();
template <field_rc rec> extern void ppc_fabs();
template <field_rc rec> extern void ppc_fnabs();
template <field_rc rec> extern void ppc_fneg();
template <field_rc rec> extern void ppc_fsel();
template <field_rc rec> extern void ppc_fres();
template <field_rc rec> extern void ppc_fsqrts();
template <field_rc rec> extern void ppc_fsqrt();
template <field_rc rec> extern void ppc_frsqrte();
template <field_rc rec> extern void ppc_frsp();
template <field_rc rec> extern void ppc_fctiw();
template <field_rc rec> extern void ppc_fctiwz();
template <field_rc rec> extern void ppc_fadd(uint32_t instr);
template <field_rc rec> extern void ppc_fsub(uint32_t instr);
template <field_rc rec> extern void ppc_fmul(uint32_t instr);
template <field_rc rec> extern void ppc_fdiv(uint32_t instr);
template <field_rc rec> extern void ppc_fadds(uint32_t instr);
template <field_rc rec> extern void ppc_fsubs(uint32_t instr);
template <field_rc rec> extern void ppc_fmuls(uint32_t instr);
template <field_rc rec> extern void ppc_fdivs(uint32_t instr);
template <field_rc rec> extern void ppc_fmadd(uint32_t instr);
template <field_rc rec> extern void ppc_fmsub(uint32_t instr);
template <field_rc rec> extern void ppc_fnmadd(uint32_t instr);
template <field_rc rec> extern void ppc_fnmsub(uint32_t instr);
template <field_rc rec> extern void ppc_fmadds(uint32_t instr);
template <field_rc rec> extern void ppc_fmsubs(uint32_t instr);
template <field_rc rec> extern void ppc_fnmadds(uint32_t instr);
template <field_rc rec> extern void ppc_fnmsubs(uint32_t instr);
template <field_rc rec> extern void ppc_fabs(uint32_t instr);
template <field_rc rec> extern void ppc_fnabs(uint32_t instr);
template <field_rc rec> extern void ppc_fneg(uint32_t instr);
template <field_rc rec> extern void ppc_fsel(uint32_t instr);
template <field_rc rec> extern void ppc_fres(uint32_t instr);
template <field_rc rec> extern void ppc_fsqrts(uint32_t instr);
template <field_rc rec> extern void ppc_fsqrt(uint32_t instr);
template <field_rc rec> extern void ppc_frsqrte(uint32_t instr);
template <field_rc rec> extern void ppc_frsp(uint32_t instr);
template <field_rc rec> extern void ppc_fctiw(uint32_t instr);
template <field_rc rec> extern void ppc_fctiwz(uint32_t instr);
extern void ppc_fcmpo();
extern void ppc_fcmpu();
extern void ppc_fcmpo(uint32_t instr);
extern void ppc_fcmpu(uint32_t instr);
// Power-specific instructions
template <field_rc rec, field_ov ov> extern void power_abs();
extern void power_clcs();
template <field_rc rec, field_ov ov> extern void power_div();
template <field_rc rec, field_ov ov> extern void power_divs();
template <field_rc rec, field_ov ov> extern void power_doz();
extern void power_dozi();
template <field_rc rec> extern void power_lscbx();
template <field_rc rec> extern void power_maskg();
template <field_rc rec> extern void power_maskir();
template <field_rc rec, field_ov ov> extern void power_mul();
template <field_rc rec, field_ov ov> extern void power_nabs();
extern void power_rlmi();
template <field_rc rec> extern void power_rrib();
template <field_rc rec> extern void power_sle();
template <field_rc rec> extern void power_sleq();
template <field_rc rec> extern void power_sliq();
template <field_rc rec> extern void power_slliq();
template <field_rc rec> extern void power_sllq();
template <field_rc rec> extern void power_slq();
template <field_rc rec> extern void power_sraiq();
template <field_rc rec> extern void power_sraq();
template <field_rc rec> extern void power_sre();
template <field_rc rec> extern void power_srea();
template <field_rc rec> extern void power_sreq();
template <field_rc rec> extern void power_sriq();
template <field_rc rec> extern void power_srliq();
template <field_rc rec> extern void power_srlq();
template <field_rc rec> extern void power_srq();
template <field_rc rec, field_ov ov> extern void power_abs(uint32_t instr);
extern void power_clcs(uint32_t instr);
template <field_rc rec, field_ov ov> extern void power_div(uint32_t instr);
template <field_rc rec, field_ov ov> extern void power_divs(uint32_t instr);
template <field_rc rec, field_ov ov> extern void power_doz(uint32_t instr);
extern void power_dozi(uint32_t instr);
template <field_rc rec> extern void power_lscbx(uint32_t instr);
template <field_rc rec> extern void power_maskg(uint32_t instr);
template <field_rc rec> extern void power_maskir(uint32_t instr);
template <field_rc rec, field_ov ov> extern void power_mul(uint32_t instr);
template <field_rc rec, field_ov ov> extern void power_nabs(uint32_t instr);
extern void power_rlmi(uint32_t instr);
template <field_rc rec> extern void power_rrib(uint32_t instr);
template <field_rc rec> extern void power_sle(uint32_t instr);
template <field_rc rec> extern void power_sleq(uint32_t instr);
template <field_rc rec> extern void power_sliq(uint32_t instr);
template <field_rc rec> extern void power_slliq(uint32_t instr);
template <field_rc rec> extern void power_sllq(uint32_t instr);
template <field_rc rec> extern void power_slq(uint32_t instr);
template <field_rc rec> extern void power_sraiq(uint32_t instr);
template <field_rc rec> extern void power_sraq(uint32_t instr);
template <field_rc rec> extern void power_sre(uint32_t instr);
template <field_rc rec> extern void power_srea(uint32_t instr);
template <field_rc rec> extern void power_sreq(uint32_t instr);
template <field_rc rec> extern void power_sriq(uint32_t instr);
template <field_rc rec> extern void power_srliq(uint32_t instr);
template <field_rc rec> extern void power_srlq(uint32_t instr);
template <field_rc rec> extern void power_srq(uint32_t instr);
} // namespace dppc_interpreter
// AltiVec instructions
@ -645,7 +635,7 @@ template <field_rc rec> extern void power_srq();
extern uint64_t get_virt_time_ns(void);
extern void ppc_main_opcode(void);
extern void ppc_main_opcode(uint32_t instr);
extern void ppc_exec(void);
extern void ppc_exec_single(void);
extern void ppc_exec_until(uint32_t goal_addr);

View File

@ -195,17 +195,16 @@ void ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits) {
throw std::invalid_argument(exc_descriptor);
}
void ppc_floating_point_exception() {
LOG_F(ERROR, "Floating point exception at 0x%08x for instruction 0x%08x",
ppc_state.pc, ppc_cur_instruction);
void ppc_floating_point_exception(uint32_t instr) {
LOG_F(ERROR, "Floating point exception at 0x%08x for instruction 0x%08x", ppc_state.pc, instr);
// mmu_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::FPU_EXCEPTION);
}
void ppc_alignment_exception(uint32_t ea)
void ppc_alignment_exception(uint32_t ea, uint32_t instr)
{
uint32_t dsisr;
switch (ppc_cur_instruction & 0xfc000000) {
switch (instr & 0xfc000000) {
case 0x80000000: // lwz
case 0x90000000: // stw
case 0xa0000000: // lhz
@ -227,11 +226,11 @@ void ppc_alignment_exception(uint32_t ea)
case 0xd4000000: // stfsu
case 0xdc000000: // stfdu
// indirect with immediate index
dsisr = ((ppc_cur_instruction >> 12) & 0x00004000) // bit 17 — Set to bit 5 of the instruction.
| ((ppc_cur_instruction >> 17) & 0x00003c00); // bits 1821 - set to bits 14 of the instruction.
dsisr = ((instr >> 12) & 0x00004000) // bit 17 — Set to bit 5 of the instruction.
| ((instr >> 17) & 0x00003c00); // bits 1821 - set to bits 14 of the instruction.
break;
case 0x7c000000:
switch (ppc_cur_instruction & 0xfc0007ff) {
switch (instr & 0xfc0007ff) {
case 0x7c000028: // lwarx (invalid form - bits 15-21 of DSISR are identical to those of lwz)
case 0x7c0002aa: // lwax (64-bit only)
case 0x7c00042a: // lswx
@ -265,12 +264,12 @@ void ppc_alignment_exception(uint32_t ea)
case 0x7c00056e: // stfsux
case 0x7c0005ee: // stfdux
indirect_with_index:
dsisr = ((ppc_cur_instruction << 14) & 0x00018000) // bits 1516 - set to bits 2930 of the instruction.
| ((ppc_cur_instruction << 8) & 0x00004000) // bit 17 - set to bit 25 of the instruction.
| ((ppc_cur_instruction << 3) & 0x00003c00); // bits 1821 - set to bits 2124 of the instruction.
dsisr = ((instr << 14) & 0x00018000) // bits 1516 - set to bits 2930 of the instruction.
| ((instr << 8) & 0x00004000) // bit 17 - set to bit 25 of the instruction.
| ((instr << 3) & 0x00003c00); // bits 1821 - set to bits 2124 of the instruction.
break;
case 0x7c0007ec:
if ((ppc_cur_instruction & 0xffe007ff) == 0x7c0007ec) // dcbz
if ((instr & 0xffe007ff) == 0x7c0007ec) // dcbz
goto indirect_with_index;
/* fallthrough */
default:
@ -281,31 +280,31 @@ indirect_with_index:
unexpected_instruction:
dsisr = 0;
LOG_F(ERROR, "Alignment exception from unexpected instruction 0x%08x",
ppc_cur_instruction);
instr);
}
// bits 2226 - Set to bits 610 (source or destination) of the instruction.
// Undefined for dcbz.
dsisr |= ((ppc_cur_instruction >> 16) & 0x000003e0);
dsisr |= ((instr >> 16) & 0x000003e0);
if ((ppc_cur_instruction & 0xfc000000) == 0xb8000000) { // lmw
if ((instr & 0xfc000000) == 0xb8000000) { // lmw
LOG_F(ERROR, "Alignment exception from instruction 0x%08x (lmw). "
"What to set DSISR bits 27-31?", ppc_cur_instruction);
// dsisr |= ((ppc_cur_instruction >> ?) & 0x0000001f); // bits 2731
}
else if ((ppc_cur_instruction & 0xfc0007ff) == 0x7c0004aa) { // lswi
"What to set DSISR bits 27-31?", instr);
// dsisr |= ((instr >> ?) & 0x0000001f); // bits 2731
}
else if ((instr & 0xfc0007ff) == 0x7c0004aa) { // lswi
LOG_F(ERROR, "Alignment exception from instruction 0x%08x (lswi). "
"What to set DSISR bits 27-31?", ppc_cur_instruction);
// dsisr |= ((ppc_cur_instruction >> ?) & 0x0000001f); // bits 2731
}
else if ((ppc_cur_instruction & 0xfc0007ff) == 0x7c00042a) { // lswx
"What to set DSISR bits 27-31?", instr);
// dsisr |= ((instr >> ?) & 0x0000001f); // bits 2731
}
else if ((instr & 0xfc0007ff) == 0x7c00042a) { // lswx
LOG_F(ERROR, "Alignment exception from instruction 0x%08x (lswx). "
"What to set DSISR bits 27-31?", ppc_cur_instruction);
// dsisr |= ((ppc_cur_instruction >> ?) & 0x0000001f); // bits 2731
"What to set DSISR bits 27-31?", instr);
// dsisr |= ((instr >> ?) & 0x0000001f); // bits 2731
}
else {
// bits 2731 - Set to bits 1115 of the instruction (rA)
dsisr |= ((ppc_cur_instruction >> 16) & 0x0000001f);
dsisr |= ((instr >> 16) & 0x0000001f);
}
ppc_state.spr[SPR::DSISR] = dsisr;

View File

@ -62,7 +62,6 @@ Po_Cause power_off_reason = po_enter_debugger;
SetPRS ppc_state;
uint32_t ppc_cur_instruction; // Current instruction for the PPC
uint32_t ppc_next_instruction_address; // Used for branching, setting up the NIA
unsigned exec_flags; // execution control flags
@ -185,7 +184,7 @@ static PPCOpcode OpcodeGrabber[64];
/** Lookup tables for branch instructions. */
const static PPCOpcode SubOpcode16Grabber[] = {
dppc_interpreter::ppc_bc<LK0, AA0>, // bc
dppc_interpreter::ppc_bc<LK0, AA0>, // bc
dppc_interpreter::ppc_bc<LK1, AA0>, // bcl
dppc_interpreter::ppc_bc<LK0, AA1>, // bca
dppc_interpreter::ppc_bc<LK1, AA1>}; // bcla
@ -229,97 +228,96 @@ void ppc_release_int() {
/** Opcode decoding functions. */
void ppc_opcode16() {
SubOpcode16Grabber[ppc_cur_instruction & 3]();
static void ppc_opcode16(uint32_t instr) {
SubOpcode16Grabber[instr & 3](instr);
}
void ppc_opcode18() {
SubOpcode18Grabber[ppc_cur_instruction & 3]();
static void ppc_opcode18(uint32_t instr) {
SubOpcode18Grabber[instr & 3](instr);
}
template<field_601 for601>
void ppc_opcode19() {
uint16_t subop_grab = ppc_cur_instruction & 0x7FF;
void ppc_opcode19(uint32_t instr) {
uint16_t subop_grab = instr & 0x7FF;
switch (subop_grab) {
case 0:
ppc_mcrf();
ppc_mcrf(instr);
break;
case 32:
ppc_bclr<LK0>();
ppc_bclr<LK0>(instr);
break;
case 33:
ppc_bclr<LK1>();
ppc_bclr<LK1>(instr);
break;
case 66:
ppc_crnor();
ppc_crnor(instr);
break;
case 100:
ppc_rfi();
ppc_rfi(instr);
break;
case 258:
ppc_crandc();
ppc_crandc(instr);
break;
case 300:
ppc_isync();
ppc_isync(instr);
break;
case 386:
ppc_crxor();
ppc_crxor(instr);
break;
case 450:
ppc_crnand();
ppc_crnand(instr);
break;
case 514:
ppc_crand();
ppc_crand(instr);
break;
case 578:
ppc_creqv();
ppc_creqv(instr);
break;
case 834:
ppc_crorc();
ppc_crorc(instr);
break;
case 898:
ppc_cror();
ppc_cror(instr);
break;
case 1056:
ppc_bcctr<LK0, for601>();
ppc_bcctr<LK0, for601>(instr);
break;
case 1057:
ppc_bcctr<LK1, for601>();
ppc_bcctr<LK1, for601>(instr);
break;
default:
ppc_illegalop();
}
}
template void ppc_opcode19<NOT601>();
template void ppc_opcode19<IS601>();
template void ppc_opcode19<NOT601>(uint32_t);
template void ppc_opcode19<IS601>(uint32_t);
void ppc_opcode31() {
uint16_t subop_grab = ppc_cur_instruction & 0x7FFUL;
SubOpcode31Grabber[subop_grab]();
void ppc_opcode31(uint32_t instr) {
uint16_t subop_grab = instr & 0x7FFUL;
SubOpcode31Grabber[subop_grab](instr);
}
void ppc_opcode59() {
uint16_t subop_grab = ppc_cur_instruction & 0x3FUL;
SubOpcode59Grabber[subop_grab]();
void ppc_opcode59(uint32_t instr) {
uint16_t subop_grab = instr & 0x3FUL;
SubOpcode59Grabber[subop_grab](instr);
}
void ppc_opcode63() {
uint16_t subop_grab = ppc_cur_instruction & 0x7FFUL;
SubOpcode63Grabber[subop_grab]();
void ppc_opcode63(uint32_t instr) {
uint16_t subop_grab = instr & 0x7FFUL;
SubOpcode63Grabber[subop_grab](instr);
}
/* Dispatch using main opcode */
void ppc_main_opcode()
{
void ppc_main_opcode(uint32_t instr) {
#ifdef CPU_PROFILING
num_executed_instrs++;
#if defined(CPU_PROFILING_OPS)
num_opcodes[ppc_cur_instruction]++;
num_opcodes[instr]++;
#endif
#endif
OpcodeGrabber[(ppc_cur_instruction >> 26) & 0x3F]();
OpcodeGrabber[(instr >> 26) & 0x3F](instr);
}
static long long cpu_now_ns() {
@ -365,6 +363,7 @@ static void ppc_exec_inner()
uint64_t max_cycles;
uint32_t page_start, eb_start, eb_end;
uint8_t* pc_real;
uint32_t instr = 0;
max_cycles = 0;
@ -376,11 +375,12 @@ static void ppc_exec_inner()
eb_end = page_start + PPC_PAGE_SIZE - 1;
exec_flags = 0;
pc_real = mmu_translate_imem(eb_start);
pc_real = mmu_translate_imem(eb_start);
instr = ppc_set_cur_instruction(pc_real);
// interpret execution block
while (power_on && ppc_state.pc < eb_end) {
ppc_main_opcode();
ppc_main_opcode(instr);
if (g_icycles++ >= max_cycles || exec_timer) {
max_cycles = process_events();
}
@ -394,7 +394,8 @@ static void ppc_exec_inner()
} else {
page_start = eb_start & PPC_PAGE_MASK;
eb_end = page_start + PPC_PAGE_SIZE - 1;
pc_real = mmu_translate_imem(eb_start);
pc_real = mmu_translate_imem(eb_start);
instr = ppc_set_cur_instruction(pc_real);
}
ppc_state.pc = eb_start;
exec_flags = 0;
@ -433,7 +434,11 @@ void ppc_exec_single()
}
mmu_translate_imem(ppc_state.pc);
ppc_main_opcode();
uint8_t* pc_real = mmu_translate_imem(ppc_state.pc);
uint32_t instr = ppc_set_cur_instruction(pc_real);
ppc_main_opcode(instr);
g_icycles++;
process_events();
@ -453,6 +458,7 @@ static void ppc_exec_until_inner(const uint32_t goal_addr)
uint64_t max_cycles;
uint32_t page_start, eb_start, eb_end;
uint8_t* pc_real;
uint32_t instr;
max_cycles = 0;
@ -464,11 +470,12 @@ static void ppc_exec_until_inner(const uint32_t goal_addr)
eb_end = page_start + PPC_PAGE_SIZE - 1;
exec_flags = 0;
pc_real = mmu_translate_imem(eb_start);
pc_real = mmu_translate_imem(eb_start);
instr = ppc_set_cur_instruction(pc_real);
// interpret execution block
while (power_on && ppc_state.pc < eb_end) {
ppc_main_opcode();
ppc_main_opcode(instr);
if (g_icycles++ >= max_cycles || exec_timer) {
max_cycles = process_events();
}
@ -482,7 +489,8 @@ static void ppc_exec_until_inner(const uint32_t goal_addr)
} else {
page_start = eb_start & PPC_PAGE_MASK;
eb_end = page_start + PPC_PAGE_SIZE - 1;
pc_real = mmu_translate_imem(eb_start);
pc_real = mmu_translate_imem(eb_start);
instr = ppc_set_cur_instruction(pc_real);
}
ppc_state.pc = eb_start;
exec_flags = 0;
@ -520,6 +528,7 @@ static void ppc_exec_dbg_inner(const uint32_t start_addr, const uint32_t size)
uint64_t max_cycles;
uint32_t page_start, eb_start, eb_end;
uint8_t* pc_real;
uint32_t instr = 0;
max_cycles = 0;
@ -531,12 +540,13 @@ static void ppc_exec_dbg_inner(const uint32_t start_addr, const uint32_t size)
eb_end = page_start + PPC_PAGE_SIZE - 1;
exec_flags = 0;
pc_real = mmu_translate_imem(eb_start);
pc_real = mmu_translate_imem(eb_start);
instr = ppc_set_cur_instruction(pc_real);
// interpret execution block
while (power_on && (ppc_state.pc < start_addr || ppc_state.pc >= start_addr + size)
&& (ppc_state.pc < eb_end)) {
ppc_main_opcode();
ppc_main_opcode(instr);
if (g_icycles++ >= max_cycles || exec_timer) {
max_cycles = process_events();
}
@ -550,7 +560,8 @@ static void ppc_exec_dbg_inner(const uint32_t start_addr, const uint32_t size)
} else {
page_start = eb_start & PPC_PAGE_MASK;
eb_end = page_start + PPC_PAGE_SIZE - 1;
pc_real = mmu_translate_imem(eb_start);
pc_real = mmu_translate_imem(eb_start);
instr = ppc_set_cur_instruction(pc_real);
}
ppc_state.pc = eb_start;
exec_flags = 0;

View File

@ -153,8 +153,8 @@ static void ppc_update_fex() {
// Floating Point Arithmetic
template <field_rc rec>
void dppc_interpreter::ppc_fadd() {
ppc_grab_regsfpdab(ppc_cur_instruction);
void dppc_interpreter::ppc_fadd(uint32_t instr) {
ppc_grab_regsfpdab(instr);
snan_double_check(reg_a, reg_b);
max_double_check(val_reg_a, val_reg_b);
@ -168,12 +168,12 @@ void dppc_interpreter::ppc_fadd() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fadd<RC0>();
template void dppc_interpreter::ppc_fadd<RC1>();
template void dppc_interpreter::ppc_fadd<RC0>(uint32_t);
template void dppc_interpreter::ppc_fadd<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fsub() {
ppc_grab_regsfpdab(ppc_cur_instruction);
void dppc_interpreter::ppc_fsub(uint32_t instr) {
ppc_grab_regsfpdab(instr);
snan_double_check(reg_a, reg_b);
@ -186,12 +186,12 @@ void dppc_interpreter::ppc_fsub() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fsub<RC0>();
template void dppc_interpreter::ppc_fsub<RC1>();
template void dppc_interpreter::ppc_fsub<RC0>(uint32_t);
template void dppc_interpreter::ppc_fsub<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fdiv() {
ppc_grab_regsfpdab(ppc_cur_instruction);
void dppc_interpreter::ppc_fdiv(uint32_t instr) {
ppc_grab_regsfpdab(instr);
snan_double_check(reg_a, reg_b);
@ -203,12 +203,12 @@ void dppc_interpreter::ppc_fdiv() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fdiv<RC0>();
template void dppc_interpreter::ppc_fdiv<RC1>();
template void dppc_interpreter::ppc_fdiv<RC0>(uint32_t);
template void dppc_interpreter::ppc_fdiv<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fmul() {
ppc_grab_regsfpdac(ppc_cur_instruction);
void dppc_interpreter::ppc_fmul(uint32_t instr) {
ppc_grab_regsfpdac(instr);
snan_double_check(reg_a, reg_c);
@ -220,12 +220,12 @@ void dppc_interpreter::ppc_fmul() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fmul<RC0>();
template void dppc_interpreter::ppc_fmul<RC1>();
template void dppc_interpreter::ppc_fmul<RC0>(uint32_t);
template void dppc_interpreter::ppc_fmul<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fmadd() {
ppc_grab_regsfpdabc(ppc_cur_instruction);
void dppc_interpreter::ppc_fmadd(uint32_t instr) {
ppc_grab_regsfpdabc(instr);
snan_double_check(reg_a, reg_c);
snan_single_check(reg_b);
@ -238,12 +238,12 @@ void dppc_interpreter::ppc_fmadd() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fmadd<RC0>();
template void dppc_interpreter::ppc_fmadd<RC1>();
template void dppc_interpreter::ppc_fmadd<RC0>(uint32_t);
template void dppc_interpreter::ppc_fmadd<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fmsub() {
ppc_grab_regsfpdabc(ppc_cur_instruction);
void dppc_interpreter::ppc_fmsub(uint32_t instr) {
ppc_grab_regsfpdabc(instr);
snan_double_check(reg_a, reg_c);
snan_single_check(reg_b);
@ -256,12 +256,12 @@ void dppc_interpreter::ppc_fmsub() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fmsub<RC0>();
template void dppc_interpreter::ppc_fmsub<RC1>();
template void dppc_interpreter::ppc_fmsub<RC0>(uint32_t);
template void dppc_interpreter::ppc_fmsub<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fnmadd() {
ppc_grab_regsfpdabc(ppc_cur_instruction);
void dppc_interpreter::ppc_fnmadd(uint32_t instr) {
ppc_grab_regsfpdabc(instr);
snan_double_check(reg_a, reg_c);
snan_single_check(reg_b);
@ -274,12 +274,12 @@ void dppc_interpreter::ppc_fnmadd() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fnmadd<RC0>();
template void dppc_interpreter::ppc_fnmadd<RC1>();
template void dppc_interpreter::ppc_fnmadd<RC0>(uint32_t);
template void dppc_interpreter::ppc_fnmadd<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fnmsub() {
ppc_grab_regsfpdabc(ppc_cur_instruction);
void dppc_interpreter::ppc_fnmsub(uint32_t instr) {
ppc_grab_regsfpdabc(instr);
snan_double_check(reg_a, reg_c);
snan_single_check(reg_b);
@ -292,12 +292,12 @@ void dppc_interpreter::ppc_fnmsub() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fnmsub<RC0>();
template void dppc_interpreter::ppc_fnmsub<RC1>();
template void dppc_interpreter::ppc_fnmsub<RC0>(uint32_t);
template void dppc_interpreter::ppc_fnmsub<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fadds() {
ppc_grab_regsfpdab(ppc_cur_instruction);
void dppc_interpreter::ppc_fadds(uint32_t instr) {
ppc_grab_regsfpdab(instr);
snan_double_check(reg_a, reg_b);
@ -310,12 +310,12 @@ void dppc_interpreter::ppc_fadds() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fadds<RC0>();
template void dppc_interpreter::ppc_fadds<RC1>();
template void dppc_interpreter::ppc_fadds<RC0>(uint32_t);
template void dppc_interpreter::ppc_fadds<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fsubs() {
ppc_grab_regsfpdab(ppc_cur_instruction);
void dppc_interpreter::ppc_fsubs(uint32_t instr) {
ppc_grab_regsfpdab(instr);
snan_double_check(reg_a, reg_b);
@ -328,12 +328,12 @@ void dppc_interpreter::ppc_fsubs() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fsubs<RC0>();
template void dppc_interpreter::ppc_fsubs<RC1>();
template void dppc_interpreter::ppc_fsubs<RC0>(uint32_t);
template void dppc_interpreter::ppc_fsubs<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fdivs() {
ppc_grab_regsfpdab(ppc_cur_instruction);
void dppc_interpreter::ppc_fdivs(uint32_t instr) {
ppc_grab_regsfpdab(instr);
snan_double_check(reg_a, reg_b);
@ -345,12 +345,12 @@ void dppc_interpreter::ppc_fdivs() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fdivs<RC0>();
template void dppc_interpreter::ppc_fdivs<RC1>();
template void dppc_interpreter::ppc_fdivs<RC0>(uint32_t);
template void dppc_interpreter::ppc_fdivs<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fmuls() {
ppc_grab_regsfpdac(ppc_cur_instruction);
void dppc_interpreter::ppc_fmuls(uint32_t instr) {
ppc_grab_regsfpdac(instr);
snan_double_check(reg_a, reg_c);
@ -362,12 +362,12 @@ void dppc_interpreter::ppc_fmuls() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fmuls<RC0>();
template void dppc_interpreter::ppc_fmuls<RC1>();
template void dppc_interpreter::ppc_fmuls<RC0>(uint32_t);
template void dppc_interpreter::ppc_fmuls<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fmadds() {
ppc_grab_regsfpdabc(ppc_cur_instruction);
void dppc_interpreter::ppc_fmadds(uint32_t instr) {
ppc_grab_regsfpdabc(instr);
snan_double_check(reg_a, reg_c);
snan_single_check(reg_b);
@ -380,12 +380,12 @@ void dppc_interpreter::ppc_fmadds() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fmadds<RC0>();
template void dppc_interpreter::ppc_fmadds<RC1>();
template void dppc_interpreter::ppc_fmadds<RC0>(uint32_t);
template void dppc_interpreter::ppc_fmadds<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fmsubs() {
ppc_grab_regsfpdabc(ppc_cur_instruction);
void dppc_interpreter::ppc_fmsubs(uint32_t instr) {
ppc_grab_regsfpdabc(instr);
snan_double_check(reg_a, reg_c);
snan_single_check(reg_b);
@ -398,12 +398,12 @@ void dppc_interpreter::ppc_fmsubs() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fmsubs<RC0>();
template void dppc_interpreter::ppc_fmsubs<RC1>();
template void dppc_interpreter::ppc_fmsubs<RC0>(uint32_t);
template void dppc_interpreter::ppc_fmsubs<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fnmadds() {
ppc_grab_regsfpdabc(ppc_cur_instruction);
void dppc_interpreter::ppc_fnmadds(uint32_t instr) {
ppc_grab_regsfpdabc(instr);
snan_double_check(reg_a, reg_c);
snan_single_check(reg_b);
@ -416,12 +416,12 @@ void dppc_interpreter::ppc_fnmadds() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fnmadds<RC0>();
template void dppc_interpreter::ppc_fnmadds<RC1>();
template void dppc_interpreter::ppc_fnmadds<RC0>(uint32_t);
template void dppc_interpreter::ppc_fnmadds<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fnmsubs() {
ppc_grab_regsfpdabc(ppc_cur_instruction);
void dppc_interpreter::ppc_fnmsubs(uint32_t instr) {
ppc_grab_regsfpdabc(instr);
snan_double_check(reg_a, reg_c);
snan_single_check(reg_b);
@ -434,12 +434,12 @@ void dppc_interpreter::ppc_fnmsubs() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fnmsubs<RC0>();
template void dppc_interpreter::ppc_fnmsubs<RC1>();
template void dppc_interpreter::ppc_fnmsubs<RC0>(uint32_t);
template void dppc_interpreter::ppc_fnmsubs<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fabs() {
ppc_grab_regsfpdb(ppc_cur_instruction);
void dppc_interpreter::ppc_fabs(uint32_t instr) {
ppc_grab_regsfpdb(instr);
snan_single_check(reg_b);
@ -451,12 +451,12 @@ void dppc_interpreter::ppc_fabs() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fabs<RC0>();
template void dppc_interpreter::ppc_fabs<RC1>();
template void dppc_interpreter::ppc_fabs<RC0>(uint32_t);
template void dppc_interpreter::ppc_fabs<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fnabs() {
ppc_grab_regsfpdb(ppc_cur_instruction);
void dppc_interpreter::ppc_fnabs(uint32_t instr) {
ppc_grab_regsfpdb(instr);
snan_single_check(reg_b);
@ -469,12 +469,12 @@ void dppc_interpreter::ppc_fnabs() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fnabs<RC0>();
template void dppc_interpreter::ppc_fnabs<RC1>();
template void dppc_interpreter::ppc_fnabs<RC0>(uint32_t);
template void dppc_interpreter::ppc_fnabs<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fneg() {
ppc_grab_regsfpdb(ppc_cur_instruction);
void dppc_interpreter::ppc_fneg(uint32_t instr) {
ppc_grab_regsfpdb(instr);
snan_single_check(reg_b);
@ -486,12 +486,12 @@ void dppc_interpreter::ppc_fneg() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fneg<RC0>();
template void dppc_interpreter::ppc_fneg<RC1>();
template void dppc_interpreter::ppc_fneg<RC0>(uint32_t);
template void dppc_interpreter::ppc_fneg<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fsel() {
ppc_grab_regsfpdabc(ppc_cur_instruction);
void dppc_interpreter::ppc_fsel(uint32_t instr) {
ppc_grab_regsfpdabc(instr);
double ppc_dblresult64_d = (val_reg_a >= -0.0) ? val_reg_c : val_reg_b;
@ -501,12 +501,12 @@ void dppc_interpreter::ppc_fsel() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fsel<RC0>();
template void dppc_interpreter::ppc_fsel<RC1>();
template void dppc_interpreter::ppc_fsel<RC0>(uint32_t);
template void dppc_interpreter::ppc_fsel<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fsqrt() {
ppc_grab_regsfpdb(ppc_cur_instruction);
void dppc_interpreter::ppc_fsqrt(uint32_t instr) {
ppc_grab_regsfpdb(instr);
snan_single_check(reg_b);
@ -518,12 +518,12 @@ void dppc_interpreter::ppc_fsqrt() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fsqrt<RC0>();
template void dppc_interpreter::ppc_fsqrt<RC1>();
template void dppc_interpreter::ppc_fsqrt<RC0>(uint32_t);
template void dppc_interpreter::ppc_fsqrt<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fsqrts() {
ppc_grab_regsfpdb(ppc_cur_instruction);
void dppc_interpreter::ppc_fsqrts(uint32_t instr) {
ppc_grab_regsfpdb(instr);
snan_single_check(reg_b);
@ -535,12 +535,12 @@ void dppc_interpreter::ppc_fsqrts() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fsqrts<RC0>();
template void dppc_interpreter::ppc_fsqrts<RC1>();
template void dppc_interpreter::ppc_fsqrts<RC0>(uint32_t);
template void dppc_interpreter::ppc_fsqrts<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_frsqrte() {
ppc_grab_regsfpdb(ppc_cur_instruction);
void dppc_interpreter::ppc_frsqrte(uint32_t instr) {
ppc_grab_regsfpdb(instr);
snan_single_check(reg_b);
double testd2 = (double)(GET_FPR(reg_b));
@ -551,12 +551,12 @@ void dppc_interpreter::ppc_frsqrte() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_frsqrte<RC0>();
template void dppc_interpreter::ppc_frsqrte<RC1>();
template void dppc_interpreter::ppc_frsqrte<RC0>(uint32_t);
template void dppc_interpreter::ppc_frsqrte<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_frsp() {
ppc_grab_regsfpdb(ppc_cur_instruction);
void dppc_interpreter::ppc_frsp(uint32_t instr) {
ppc_grab_regsfpdb(instr);
snan_single_check(reg_b);
double ppc_dblresult64_d = (float)(GET_FPR(reg_b));
@ -566,12 +566,12 @@ void dppc_interpreter::ppc_frsp() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_frsp<RC0>();
template void dppc_interpreter::ppc_frsp<RC1>();
template void dppc_interpreter::ppc_frsp<RC0>(uint32_t);
template void dppc_interpreter::ppc_frsp<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fres() {
ppc_grab_regsfpdb(ppc_cur_instruction);
void dppc_interpreter::ppc_fres(uint32_t instr) {
ppc_grab_regsfpdb(instr);
snan_single_check(reg_b);
@ -594,11 +594,11 @@ void dppc_interpreter::ppc_fres() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fres<RC0>();
template void dppc_interpreter::ppc_fres<RC1>();
template void dppc_interpreter::ppc_fres<RC0>(uint32_t);
template void dppc_interpreter::ppc_fres<RC1>(uint32_t);
static void round_to_int(const uint8_t mode, field_rc rec) {
ppc_grab_regsfpdb(ppc_cur_instruction);
static void round_to_int(uint32_t instr, const uint8_t mode, field_rc rec) {
ppc_grab_regsfpdb(instr);
double val_reg_b = GET_FPR(reg_b);
if (std::isnan(val_reg_b)) {
@ -610,7 +610,7 @@ static void round_to_int(const uint8_t mode, field_rc rec) {
if (ppc_state.fpscr & FPSCR::VE) {
ppc_state.fpscr |= FPSCR::FEX; // VX=1 and VE=1 cause FEX to be set
ppc_floating_point_exception();
ppc_floating_point_exception(instr);
} else {
ppc_state.fpr[reg_d].int64_r = 0xFFF8000080000000ULL;
}
@ -621,7 +621,7 @@ static void round_to_int(const uint8_t mode, field_rc rec) {
if (ppc_state.fpscr & FPSCR::VE) {
ppc_state.fpscr |= FPSCR::FEX; // VX=1 and VE=1 cause FEX to be set
ppc_floating_point_exception();
ppc_floating_point_exception(instr);
} else {
if (val_reg_b >= 0.0f)
ppc_state.fpr[reg_d].int64_r = 0xFFF800007FFFFFFFULL;
@ -655,37 +655,37 @@ static void round_to_int(const uint8_t mode, field_rc rec) {
}
template <field_rc rec>
void dppc_interpreter::ppc_fctiw() {
round_to_int(ppc_state.fpscr & 0x3, rec);
void dppc_interpreter::ppc_fctiw(uint32_t instr) {
round_to_int(instr, ppc_state.fpscr & 0x3, rec);
}
template void dppc_interpreter::ppc_fctiw<RC0>();
template void dppc_interpreter::ppc_fctiw<RC1>();
template void dppc_interpreter::ppc_fctiw<RC0>(uint32_t);
template void dppc_interpreter::ppc_fctiw<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_fctiwz() {
round_to_int(1, rec);
void dppc_interpreter::ppc_fctiwz(uint32_t instr) {
round_to_int(instr, 1, rec);
}
template void dppc_interpreter::ppc_fctiwz<RC0>();
template void dppc_interpreter::ppc_fctiwz<RC1>();
template void dppc_interpreter::ppc_fctiwz<RC0>(uint32_t);
template void dppc_interpreter::ppc_fctiwz<RC1>(uint32_t);
// Floating Point Store and Load
void dppc_interpreter::ppc_lfs() {
ppc_grab_regsfpdia(ppc_cur_instruction);
uint32_t ea = int32_t(int16_t(ppc_cur_instruction));
void dppc_interpreter::ppc_lfs(uint32_t instr) {
ppc_grab_regsfpdia(instr);
uint32_t ea = int32_t(int16_t(instr));
ea += (reg_a) ? val_reg_a : 0;
uint32_t result = mmu_read_vmem<uint32_t>(ea);
uint32_t result = mmu_read_vmem<uint32_t>(ea, instr);
ppc_state.fpr[reg_d].dbl64_r = *(float*)(&result);
}
void dppc_interpreter::ppc_lfsu() {
ppc_grab_regsfpdia(ppc_cur_instruction);
void dppc_interpreter::ppc_lfsu(uint32_t instr) {
ppc_grab_regsfpdia(instr);
if (reg_a) {
uint32_t ea = int32_t(int16_t(ppc_cur_instruction));
uint32_t ea = int32_t(int16_t(instr));
ea += (reg_a) ? val_reg_a : 0;
uint32_t result = mmu_read_vmem<uint32_t>(ea);
uint32_t result = mmu_read_vmem<uint32_t>(ea, instr);
ppc_state.fpr[reg_d].dbl64_r = *(float*)(&result);
ppc_state.gpr[reg_a] = ea;
} else {
@ -693,18 +693,18 @@ void dppc_interpreter::ppc_lfsu() {
}
}
void dppc_interpreter::ppc_lfsx() {
ppc_grab_regsfpdiab(ppc_cur_instruction);
void dppc_interpreter::ppc_lfsx(uint32_t instr) {
ppc_grab_regsfpdiab(instr);
uint32_t ea = val_reg_b + (reg_a ? val_reg_a : 0);
uint32_t result = mmu_read_vmem<uint32_t>(ea);
uint32_t result = mmu_read_vmem<uint32_t>(ea, instr);
ppc_state.fpr[reg_d].dbl64_r = *(float*)(&result);
}
void dppc_interpreter::ppc_lfsux() {
ppc_grab_regsfpdiab(ppc_cur_instruction);
void dppc_interpreter::ppc_lfsux(uint32_t instr) {
ppc_grab_regsfpdiab(instr);
if (reg_a) {
uint32_t ea = val_reg_a + val_reg_b;
uint32_t result = mmu_read_vmem<uint32_t>(ea);
uint32_t result = mmu_read_vmem<uint32_t>(ea, instr);
ppc_state.fpr[reg_d].dbl64_r = *(float*)(&result);
ppc_state.gpr[reg_a] = ea;
} else {
@ -712,20 +712,20 @@ void dppc_interpreter::ppc_lfsux() {
}
}
void dppc_interpreter::ppc_lfd() {
ppc_grab_regsfpdia(ppc_cur_instruction);
uint32_t ea = int32_t(int16_t(ppc_cur_instruction));
void dppc_interpreter::ppc_lfd(uint32_t instr) {
ppc_grab_regsfpdia(instr);
uint32_t ea = int32_t(int16_t(instr));
ea += (reg_a) ? val_reg_a : 0;
uint64_t ppc_result64_d = mmu_read_vmem<uint64_t>(ea);
uint64_t ppc_result64_d = mmu_read_vmem<uint64_t>(ea, instr);
ppc_store_dfpresult_int(reg_d, ppc_result64_d);
}
void dppc_interpreter::ppc_lfdu() {
ppc_grab_regsfpdia(ppc_cur_instruction);
void dppc_interpreter::ppc_lfdu(uint32_t instr) {
ppc_grab_regsfpdia(instr);
if (reg_a != 0) {
uint32_t ea = int32_t(int16_t(ppc_cur_instruction));
uint32_t ea = int32_t(int16_t(instr));
ea += val_reg_a;
uint64_t ppc_result64_d = mmu_read_vmem<uint64_t>(ea);
uint64_t ppc_result64_d = mmu_read_vmem<uint64_t>(ea, instr);
ppc_store_dfpresult_int(reg_d, ppc_result64_d);
ppc_state.gpr[reg_a] = ea;
} else {
@ -733,18 +733,18 @@ void dppc_interpreter::ppc_lfdu() {
}
}
void dppc_interpreter::ppc_lfdx() {
ppc_grab_regsfpdiab(ppc_cur_instruction);
void dppc_interpreter::ppc_lfdx(uint32_t instr) {
ppc_grab_regsfpdiab(instr);
uint32_t ea = val_reg_b + (reg_a ? val_reg_a : 0);
uint64_t ppc_result64_d = mmu_read_vmem<uint64_t>(ea);
uint64_t ppc_result64_d = mmu_read_vmem<uint64_t>(ea, instr);
ppc_store_dfpresult_int(reg_d, ppc_result64_d);
}
void dppc_interpreter::ppc_lfdux() {
ppc_grab_regsfpdiab(ppc_cur_instruction);
void dppc_interpreter::ppc_lfdux(uint32_t instr) {
ppc_grab_regsfpdiab(instr);
if (reg_a) {
uint32_t ea = val_reg_a + val_reg_b;
uint64_t ppc_result64_d = mmu_read_vmem<uint64_t>(ea);
uint64_t ppc_result64_d = mmu_read_vmem<uint64_t>(ea, instr);
ppc_store_dfpresult_int(reg_d, ppc_result64_d);
ppc_state.gpr[reg_a] = ea;
} else {
@ -752,105 +752,105 @@ void dppc_interpreter::ppc_lfdux() {
}
}
void dppc_interpreter::ppc_stfs() {
ppc_grab_regsfpsia(ppc_cur_instruction);
uint32_t ea = int32_t(int16_t(ppc_cur_instruction));
void dppc_interpreter::ppc_stfs(uint32_t instr) {
ppc_grab_regsfpsia(instr);
uint32_t ea = int32_t(int16_t(instr));
ea += (reg_a) ? val_reg_a : 0;
float result = float(ppc_state.fpr[reg_s].dbl64_r);
mmu_write_vmem<uint32_t>(ea, *(uint32_t*)(&result));
mmu_write_vmem<uint32_t>(ea, instr, *(uint32_t*)(&result));
}
void dppc_interpreter::ppc_stfsu() {
ppc_grab_regsfpsia(ppc_cur_instruction);
void dppc_interpreter::ppc_stfsu(uint32_t instr) {
ppc_grab_regsfpsia(instr);
if (reg_a != 0) {
uint32_t ea = int32_t(int16_t(ppc_cur_instruction));
uint32_t ea = int32_t(int16_t(instr));
ea += val_reg_a;
float result = float(ppc_state.fpr[reg_s].dbl64_r);
mmu_write_vmem<uint32_t>(ea, *(uint32_t*)(&result));
mmu_write_vmem<uint32_t>(ea, instr, *(uint32_t*)(&result));
ppc_state.gpr[reg_a] = ea;
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
void dppc_interpreter::ppc_stfsx() {
ppc_grab_regsfpsiab(ppc_cur_instruction);
void dppc_interpreter::ppc_stfsx(uint32_t instr) {
ppc_grab_regsfpsiab(instr);
uint32_t ea = val_reg_b + (reg_a ? val_reg_a : 0);
float result = float(ppc_state.fpr[reg_s].dbl64_r);
mmu_write_vmem<uint32_t>(ea, *(uint32_t*)(&result));
mmu_write_vmem<uint32_t>(ea, instr, *(uint32_t*)(&result));
}
void dppc_interpreter::ppc_stfsux() {
ppc_grab_regsfpsiab(ppc_cur_instruction);
void dppc_interpreter::ppc_stfsux(uint32_t instr) {
ppc_grab_regsfpsiab(instr);
if (reg_a) {
uint32_t ea = val_reg_a + val_reg_b;
float result = float(ppc_state.fpr[reg_s].dbl64_r);
mmu_write_vmem<uint32_t>(ea, *(uint32_t*)(&result));
mmu_write_vmem<uint32_t>(ea, instr, *(uint32_t*)(&result));
ppc_state.gpr[reg_a] = ea;
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
void dppc_interpreter::ppc_stfd() {
ppc_grab_regsfpsia(ppc_cur_instruction);
uint32_t ea = int32_t(int16_t(ppc_cur_instruction));
void dppc_interpreter::ppc_stfd(uint32_t instr) {
ppc_grab_regsfpsia(instr);
uint32_t ea = int32_t(int16_t(instr));
ea += reg_a ? val_reg_a : 0;
mmu_write_vmem<uint64_t>(ea, ppc_state.fpr[reg_s].int64_r);
mmu_write_vmem<uint64_t>(ea, instr, ppc_state.fpr[reg_s].int64_r);
}
void dppc_interpreter::ppc_stfdu() {
ppc_grab_regsfpsia(ppc_cur_instruction);
void dppc_interpreter::ppc_stfdu(uint32_t instr) {
ppc_grab_regsfpsia(instr);
if (reg_a != 0) {
uint32_t ea = int32_t(int16_t(ppc_cur_instruction));
uint32_t ea = int32_t(int16_t(instr));
ea += val_reg_a;
mmu_write_vmem<uint64_t>(ea, ppc_state.fpr[reg_s].int64_r);
mmu_write_vmem<uint64_t>(ea, instr, ppc_state.fpr[reg_s].int64_r);
ppc_state.gpr[reg_a] = ea;
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
void dppc_interpreter::ppc_stfdx() {
ppc_grab_regsfpsiab(ppc_cur_instruction);
void dppc_interpreter::ppc_stfdx(uint32_t instr) {
ppc_grab_regsfpsiab(instr);
uint32_t ea = val_reg_b + (reg_a ? val_reg_a : 0);
mmu_write_vmem<uint64_t>(ea, ppc_state.fpr[reg_s].int64_r);
mmu_write_vmem<uint64_t>(ea, instr, ppc_state.fpr[reg_s].int64_r);
}
void dppc_interpreter::ppc_stfdux() {
ppc_grab_regsfpsiab(ppc_cur_instruction);
void dppc_interpreter::ppc_stfdux(uint32_t instr) {
ppc_grab_regsfpsiab(instr);
if (reg_a != 0) {
uint32_t ea = val_reg_a + val_reg_b;
mmu_write_vmem<uint64_t>(ea, ppc_state.fpr[reg_s].int64_r);
mmu_write_vmem<uint64_t>(ea, instr, ppc_state.fpr[reg_s].int64_r);
ppc_state.gpr[reg_a] = ea;
} else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
}
}
void dppc_interpreter::ppc_stfiwx() {
ppc_grab_regsfpsiab(ppc_cur_instruction);
void dppc_interpreter::ppc_stfiwx(uint32_t instr) {
ppc_grab_regsfpsiab(instr);
uint32_t ea = val_reg_b + (reg_a ? val_reg_a : 0);
mmu_write_vmem<uint32_t>(ea, uint32_t(ppc_state.fpr[reg_s].int64_r));
mmu_write_vmem<uint32_t>(ea, instr, uint32_t(ppc_state.fpr[reg_s].int64_r));
}
// Floating Point Register Transfer
template <field_rc rec>
void dppc_interpreter::ppc_fmr() {
ppc_grab_regsfpdb(ppc_cur_instruction);
void dppc_interpreter::ppc_fmr(uint32_t instr) {
ppc_grab_regsfpdb(instr);
ppc_state.fpr[reg_d].dbl64_r = ppc_state.fpr[reg_b].dbl64_r;
if (rec)
ppc_update_cr1();
}
template void dppc_interpreter::ppc_fmr<RC0>();
template void dppc_interpreter::ppc_fmr<RC1>();
template void dppc_interpreter::ppc_fmr<RC0>(uint32_t);
template void dppc_interpreter::ppc_fmr<RC1>(uint32_t);
template <field_601 for601, field_rc rec>
void dppc_interpreter::ppc_mffs() {
int reg_d = (ppc_cur_instruction >> 21) & 31;
void dppc_interpreter::ppc_mffs(uint32_t instr) {
int reg_d = (instr >> 21) & 31;
ppc_state.fpr[reg_d].int64_r = uint64_t(ppc_state.fpscr) | (for601 ? 0xFFFFFFFF00000000ULL : 0xFFF8000000000000ULL);
@ -858,15 +858,15 @@ void dppc_interpreter::ppc_mffs() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_mffs<NOT601, RC0>();
template void dppc_interpreter::ppc_mffs<NOT601, RC1>();
template void dppc_interpreter::ppc_mffs<IS601, RC0>();
template void dppc_interpreter::ppc_mffs<IS601, RC1>();
template void dppc_interpreter::ppc_mffs<NOT601, RC0>(uint32_t);
template void dppc_interpreter::ppc_mffs<NOT601, RC1>(uint32_t);
template void dppc_interpreter::ppc_mffs<IS601, RC0>(uint32_t);
template void dppc_interpreter::ppc_mffs<IS601, RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_mtfsf() {
int reg_b = (ppc_cur_instruction >> 11) & 0x1F;
uint8_t fm = (ppc_cur_instruction >> 17) & 0xFF;
void dppc_interpreter::ppc_mtfsf(uint32_t instr) {
int reg_b = (instr >> 11) & 0x1F;
uint8_t fm = (instr >> 17) & 0xFF;
uint32_t cr_mask = 0;
@ -893,13 +893,13 @@ void dppc_interpreter::ppc_mtfsf() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_mtfsf<RC0>();
template void dppc_interpreter::ppc_mtfsf<RC1>();
template void dppc_interpreter::ppc_mtfsf<RC0>(uint32_t);
template void dppc_interpreter::ppc_mtfsf<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_mtfsfi() {
int crf_d = (ppc_cur_instruction >> 21) & 0x1C;
uint32_t imm = (ppc_cur_instruction << 16) & 0xF0000000UL;
void dppc_interpreter::ppc_mtfsfi(uint32_t instr) {
int crf_d = (instr >> 21) & 0x1C;
uint32_t imm = (instr << 16) & 0xF0000000UL;
// prepare field mask and ensure that neither FEX nor VX will be changed
uint32_t mask = (0xF0000000UL >> crf_d) & ~(FPSCR::FEX | FPSCR::VX);
@ -915,12 +915,12 @@ void dppc_interpreter::ppc_mtfsfi() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_mtfsfi<RC0>();
template void dppc_interpreter::ppc_mtfsfi<RC1>();
template void dppc_interpreter::ppc_mtfsfi<RC0>(uint32_t);
template void dppc_interpreter::ppc_mtfsfi<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_mtfsb0() {
int crf_d = (ppc_cur_instruction >> 21) & 0x1F;
void dppc_interpreter::ppc_mtfsb0(uint32_t instr) {
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);
}
@ -929,12 +929,12 @@ void dppc_interpreter::ppc_mtfsb0() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_mtfsb0<RC0>();
template void dppc_interpreter::ppc_mtfsb0<RC1>();
template void dppc_interpreter::ppc_mtfsb0<RC0>(uint32_t);
template void dppc_interpreter::ppc_mtfsb0<RC1>(uint32_t);
template <field_rc rec>
void dppc_interpreter::ppc_mtfsb1() {
int crf_d = (ppc_cur_instruction >> 21) & 0x1F;
void dppc_interpreter::ppc_mtfsb1(uint32_t instr) {
int crf_d = (instr >> 21) & 0x1F;
if (!crf_d || (crf_d > 2)) { // FEX and VX can't be explicitly set
ppc_state.fpscr |= (0x80000000UL >> crf_d);
}
@ -943,12 +943,12 @@ void dppc_interpreter::ppc_mtfsb1() {
ppc_update_cr1();
}
template void dppc_interpreter::ppc_mtfsb1<RC0>();
template void dppc_interpreter::ppc_mtfsb1<RC1>();
template void dppc_interpreter::ppc_mtfsb1<RC0>(uint32_t);
template void dppc_interpreter::ppc_mtfsb1<RC1>(uint32_t);
void dppc_interpreter::ppc_mcrfs() {
int crf_d = (ppc_cur_instruction >> 21) & 0x1C;
int crf_s = (ppc_cur_instruction >> 16) & 0x1C;
void dppc_interpreter::ppc_mcrfs(uint32_t instr) {
int crf_d = (instr >> 21) & 0x1C;
int crf_s = (instr >> 16) & 0x1C;
ppc_state.cr = (
(ppc_state.cr & ~(0xF0000000UL >> crf_d)) |
(((ppc_state.fpscr << crf_s) & 0xF0000000UL) >> crf_d)
@ -965,8 +965,8 @@ void dppc_interpreter::ppc_mcrfs() {
// Floating Point Comparisons
void dppc_interpreter::ppc_fcmpo() {
ppc_grab_regsfpsab(ppc_cur_instruction);
void dppc_interpreter::ppc_fcmpo(uint32_t instr) {
ppc_grab_regsfpsab(instr);
uint32_t cmp_c = 0;
@ -996,8 +996,8 @@ void dppc_interpreter::ppc_fcmpo() {
}
void dppc_interpreter::ppc_fcmpu() {
ppc_grab_regsfpsab(ppc_cur_instruction);
void dppc_interpreter::ppc_fcmpu(uint32_t instr) {
ppc_grab_regsfpsab(instr);
uint32_t cmp_c = 0;

View File

@ -741,7 +741,6 @@ uint8_t *mmu_translate_imem(uint32_t vaddr, uint32_t *paddr)
host_va = (uint8_t *)(tlb1_entry->host_va_offs_r + vaddr);
}
ppc_set_cur_instruction(host_va);
if (paddr)
*paddr = tlb1_entry->phys_tag | (vaddr & 0xFFFUL);
@ -985,13 +984,12 @@ void mmu_pat_ctx_changed()
// Forward declarations.
template <class T>
static T read_unaligned(uint32_t guest_va, uint8_t *host_va);
static T read_unaligned(uint32_t guest_va, uint32_t instr, uint8_t* host_va);
template <class T>
static void write_unaligned(uint32_t guest_va, uint8_t *host_va, T value);
static void write_unaligned(uint32_t guest_va, uint8_t* host_va, uint32_t instr, T value);
template <class T>
inline T mmu_read_vmem(uint32_t guest_va)
{
inline T mmu_read_vmem(uint32_t guest_va, uint32_t instr) {
TLBEntry *tlb1_entry, *tlb2_entry;
uint8_t *host_va;
@ -1034,7 +1032,7 @@ inline T mmu_read_vmem(uint32_t guest_va)
#endif
if (sizeof(T) == 8) {
if (guest_va & 3)
ppc_alignment_exception(guest_va);
ppc_alignment_exception(guest_va, instr);
return (
((T)tlb2_entry->rgn_desc->devobj->read(tlb2_entry->rgn_desc->start,
@ -1078,14 +1076,13 @@ inline T mmu_read_vmem(uint32_t guest_va)
}
// explicitely instantiate all required mmu_read_vmem variants
template uint8_t mmu_read_vmem<uint8_t>(uint32_t guest_va);
template uint16_t mmu_read_vmem<uint16_t>(uint32_t guest_va);
template uint32_t mmu_read_vmem<uint32_t>(uint32_t guest_va);
template uint64_t mmu_read_vmem<uint64_t>(uint32_t guest_va);
template uint8_t mmu_read_vmem<uint8_t>(uint32_t guest_va, uint32_t instr);
template uint16_t mmu_read_vmem<uint16_t>(uint32_t guest_va, uint32_t instr);
template uint32_t mmu_read_vmem<uint32_t>(uint32_t guest_va, uint32_t instr);
template uint64_t mmu_read_vmem<uint64_t>(uint32_t guest_va, uint32_t instr);
template <class T>
inline void mmu_write_vmem(uint32_t guest_va, T value)
{
inline void mmu_write_vmem(uint32_t guest_va, uint32_t instr, T value) {
TLBEntry *tlb1_entry, *tlb2_entry;
uint8_t *host_va;
@ -1201,17 +1198,16 @@ inline void mmu_write_vmem(uint32_t guest_va, T value)
}
// explicitely instantiate all required mmu_write_vmem variants
template void mmu_write_vmem<uint8_t>(uint32_t guest_va, uint8_t value);
template void mmu_write_vmem<uint16_t>(uint32_t guest_va, uint16_t value);
template void mmu_write_vmem<uint32_t>(uint32_t guest_va, uint32_t value);
template void mmu_write_vmem<uint64_t>(uint32_t guest_va, uint64_t value);
template void mmu_write_vmem<uint8_t>(uint32_t guest_va, uint32_t instr, uint8_t value);
template void mmu_write_vmem<uint16_t>(uint32_t guest_va, uint32_t instr, uint16_t value);
template void mmu_write_vmem<uint32_t>(uint32_t guest_va, uint32_t instr, uint32_t value);
template void mmu_write_vmem<uint64_t>(uint32_t guest_va, uint32_t instr, uint64_t value);
template <class T>
static T read_unaligned(uint32_t guest_va, uint8_t *host_va)
{
static T read_unaligned(uint32_t guest_va, uint8_t* host_va, uint32_t instr) {
if ((sizeof(T) == 8) && (guest_va & 3)) {
#ifndef PPC_TESTS
ppc_alignment_exception(guest_va);
ppc_alignment_exception(guest_va, instr);
#endif
}
@ -1226,7 +1222,7 @@ static T read_unaligned(uint32_t guest_va, uint8_t *host_va)
// Because such accesses suffer a performance penalty, they will be
// presumably very rare so don't waste time optimizing the code below.
for (int i = 0; i < sizeof(T); guest_va++, i++) {
result = (result << 8) | mmu_read_vmem<uint8_t>(guest_va);
result = (result << 8) | mmu_read_vmem<uint8_t>(guest_va, instr);
}
} else {
#ifdef MMU_PROFILING
@ -1247,12 +1243,12 @@ static T read_unaligned(uint32_t guest_va, uint8_t *host_va)
}
// explicitely instantiate all required read_unaligned variants
template uint16_t read_unaligned<uint16_t>(uint32_t guest_va, uint8_t *host_va);
template uint32_t read_unaligned<uint32_t>(uint32_t guest_va, uint8_t *host_va);
template uint64_t read_unaligned<uint64_t>(uint32_t guest_va, uint8_t *host_va);
template uint16_t read_unaligned<uint16_t>(uint32_t guest_va, uint8_t* host_va, uint32_t instr);
template uint32_t read_unaligned<uint32_t>(uint32_t guest_va, uint8_t* host_va, uint32_t instr);
template uint64_t read_unaligned<uint64_t>(uint32_t guest_va, uint8_t* host_va, uint32_t instr);
template <class T>
static void write_unaligned(uint32_t guest_va, uint8_t *host_va, T value)
static void write_unaligned(uint32_t guest_va, uint8_t *host_va, uint32_t instr, T value)
{
if ((sizeof(T) == 8) && (guest_va & 3)) {
#ifndef PPC_TESTS
@ -1272,7 +1268,7 @@ static void write_unaligned(uint32_t guest_va, uint8_t *host_va, T value)
uint32_t shift = (sizeof(T) - 1) * 8;
for (int i = 0; i < sizeof(T); shift -= 8, guest_va++, i++) {
mmu_write_vmem<uint8_t>(guest_va, (value >> shift) & 0xFF);
mmu_write_vmem<uint8_t>(guest_va, uint32_t instr, (value >> shift) & 0xFF);
}
} else {
#ifdef MMU_PROFILING
@ -1296,9 +1292,12 @@ static void write_unaligned(uint32_t guest_va, uint8_t *host_va, T value)
}
// explicitely instantiate all required write_unaligned variants
template void write_unaligned<uint16_t>(uint32_t guest_va, uint8_t *host_va, uint16_t value);
template void write_unaligned<uint32_t>(uint32_t guest_va, uint8_t *host_va, uint32_t value);
template void write_unaligned<uint64_t>(uint32_t guest_va, uint8_t *host_va, uint64_t value);
template void write_unaligned<uint16_t>(
uint32_t guest_va, uint8_t* host_va, uint32_t instr, uint16_t value);
template void write_unaligned<uint32_t>(
uint32_t guest_va, uint8_t* host_va, uint32_t instr, uint32_t value);
template void write_unaligned<uint64_t>(
uint32_t guest_va, uint8_t* host_va, uint32_t instr, uint64_t value);
/* MMU profiling. */
@ -1426,7 +1425,7 @@ public:
};
#endif
uint64_t mem_read_dbg(uint32_t virt_addr, uint32_t size) {
uint64_t mem_read_dbg(uint32_t virt_addr, uint32_t instr, uint32_t size) {
uint32_t save_dsisr, save_dar;
uint64_t ret_val;
@ -1438,19 +1437,19 @@ uint64_t mem_read_dbg(uint32_t virt_addr, uint32_t size) {
try {
switch (size) {
case 1:
ret_val = mmu_read_vmem<uint8_t>(virt_addr);
ret_val = mmu_read_vmem<uint8_t>(virt_addr, instr);
break;
case 2:
ret_val = mmu_read_vmem<uint16_t>(virt_addr);
ret_val = mmu_read_vmem<uint16_t>(virt_addr, instr);
break;
case 4:
ret_val = mmu_read_vmem<uint32_t>(virt_addr);
ret_val = mmu_read_vmem<uint32_t>(virt_addr, instr);
break;
case 8:
ret_val = mmu_read_vmem<uint64_t>(virt_addr);
ret_val = mmu_read_vmem<uint64_t>(virt_addr, instr);
break;
default:
ret_val = mmu_read_vmem<uint8_t>(virt_addr);
ret_val = mmu_read_vmem<uint8_t>(virt_addr, instr);
}
} catch (std::invalid_argument& exc) {
/* restore MMU-related CPU state */

View File

@ -130,8 +130,8 @@ uint8_t *mmu_translate_imem(uint32_t vaddr, uint32_t *paddr = nullptr);
bool mmu_translate_dbg(uint32_t guest_va, uint32_t &guest_pa);
template <class T>
extern T mmu_read_vmem(uint32_t guest_va);
extern T mmu_read_vmem(uint32_t guest_va, uint32_t instr);
template <class T>
extern void mmu_write_vmem(uint32_t guest_va, T value);
extern void mmu_write_vmem(uint32_t guest_va, uint32_t instr, T value);
#endif // PPCMMU_H

File diff suppressed because it is too large Load Diff

View File

@ -36,12 +36,11 @@ using namespace std;
int ntested; // number of tested instructions
int nfailed; // number of failed instructions
void xer_ov_test(string mnem, uint32_t opcode) {
static void xer_ov_test(string mnem, uint32_t opcode) {
ppc_state.gpr[3] = 2;
ppc_state.gpr[4] = 2;
ppc_state.spr[SPR::XER] = 0xFFFFFFFF;
ppc_cur_instruction = opcode;
ppc_main_opcode();
ppc_main_opcode(opcode);
if (ppc_state.spr[SPR::XER] & 0x40000000UL) {
cout << "Invalid " << mnem << " emulation! XER[OV] should not be set." << endl;
nfailed++;
@ -145,9 +144,7 @@ static void read_test_data() {
ppc_state.spr[SPR::XER] = 0;
ppc_state.cr = 0;
ppc_cur_instruction = opcode;
ppc_main_opcode();
ppc_main_opcode(opcode);
ntested++;
@ -289,9 +286,7 @@ static void read_test_float_data() {
ppc_state.cr = 0;
ppc_cur_instruction = opcode;
ppc_main_opcode();
ppc_main_opcode(opcode);
ntested++;