mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-21 07:31:34 +00:00
Take 2 of removing ppc_cur_instruction
This commit is contained in:
parent
8c42685e26
commit
72308074da
@ -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);
|
||||
|
392
cpu/ppc/ppcemu.h
392
cpu/ppc/ppcemu.h
@ -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);
|
||||
|
@ -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 18–21 - set to bits 1–4 of the instruction.
|
||||
dsisr = ((instr >> 12) & 0x00004000) // bit 17 — Set to bit 5 of the instruction.
|
||||
| ((instr >> 17) & 0x00003c00); // bits 18–21 - set to bits 1–4 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 15–16 - set to bits 29–30 of the instruction.
|
||||
| ((ppc_cur_instruction << 8) & 0x00004000) // bit 17 - set to bit 25 of the instruction.
|
||||
| ((ppc_cur_instruction << 3) & 0x00003c00); // bits 18–21 - set to bits 21–24 of the instruction.
|
||||
dsisr = ((instr << 14) & 0x00018000) // bits 15–16 - set to bits 29–30 of the instruction.
|
||||
| ((instr << 8) & 0x00004000) // bit 17 - set to bit 25 of the instruction.
|
||||
| ((instr << 3) & 0x00003c00); // bits 18–21 - set to bits 21–24 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 22–26 - Set to bits 6–10 (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 27–31
|
||||
}
|
||||
else if ((ppc_cur_instruction & 0xfc0007ff) == 0x7c0004aa) { // lswi
|
||||
"What to set DSISR bits 27-31?", instr);
|
||||
// dsisr |= ((instr >> ?) & 0x0000001f); // bits 27–31
|
||||
}
|
||||
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 27–31
|
||||
}
|
||||
else if ((ppc_cur_instruction & 0xfc0007ff) == 0x7c00042a) { // lswx
|
||||
"What to set DSISR bits 27-31?", instr);
|
||||
// dsisr |= ((instr >> ?) & 0x0000001f); // bits 27–31
|
||||
}
|
||||
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 27–31
|
||||
"What to set DSISR bits 27-31?", instr);
|
||||
// dsisr |= ((instr >> ?) & 0x0000001f); // bits 27–31
|
||||
}
|
||||
else {
|
||||
// bits 27–31 - Set to bits 11–15 of the instruction (rA)
|
||||
dsisr |= ((ppc_cur_instruction >> 16) & 0x0000001f);
|
||||
dsisr |= ((instr >> 16) & 0x0000001f);
|
||||
}
|
||||
|
||||
ppc_state.spr[SPR::DSISR] = dsisr;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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
@ -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++;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user