initial attempt to remove global variable exec_flags

This commit is contained in:
dingusdev 2024-12-20 21:25:50 -07:00
parent e63f928a3c
commit c25ad96e3a
9 changed files with 900 additions and 729 deletions

View File

@ -28,7 +28,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <debugger/debugger.h>
#if defined(PPC_BENCHMARKS)
void ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits) {
uint32_t ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits) {
power_on = false;
power_off_reason = po_benchmark_exception;
}

View File

@ -35,7 +35,7 @@ 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(uint32_t opcode) {
uint32_t dppc_interpreter::power_abs(uint32_t opcode) {
uint32_t ppc_result_d;
ppc_grab_regsda(opcode);
if (ppc_result_a == 0x80000000) {
@ -52,14 +52,15 @@ void dppc_interpreter::power_abs(uint32_t opcode) {
ppc_changecrf0(ppc_result_d);
ppc_store_iresult_reg(reg_d, ppc_result_d);
return 0;
}
template void dppc_interpreter::power_abs<RC0, OV0>(uint32_t opcode);
template void dppc_interpreter::power_abs<RC0, OV1>(uint32_t opcode);
template void dppc_interpreter::power_abs<RC1, OV0>(uint32_t opcode);
template void dppc_interpreter::power_abs<RC1, OV1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_abs<RC0, OV0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_abs<RC0, OV1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_abs<RC1, OV0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_abs<RC1, OV1>(uint32_t opcode);
void dppc_interpreter::power_clcs(uint32_t opcode) {
uint32_t dppc_interpreter::power_clcs(uint32_t opcode) {
uint32_t ppc_result_d;
ppc_grab_da(opcode);
switch (reg_a & 15) {
@ -83,10 +84,11 @@ void dppc_interpreter::power_clcs(uint32_t opcode) {
}
ppc_store_iresult_reg(reg_d, ppc_result_d);
return 0;
}
template <field_rc rec, field_ov ov>
void dppc_interpreter::power_div(uint32_t opcode) {
uint32_t dppc_interpreter::power_div(uint32_t opcode) {
uint32_t ppc_result_d;
ppc_grab_regsdab(opcode);
@ -123,15 +125,16 @@ void dppc_interpreter::power_div(uint32_t opcode) {
ppc_store_iresult_reg(reg_d, ppc_result_d);
ppc_state.spr[SPR::MQ] = remainder;
return 0;
}
template void dppc_interpreter::power_div<RC0, OV0>(uint32_t opcode);
template void dppc_interpreter::power_div<RC0, OV1>(uint32_t opcode);
template void dppc_interpreter::power_div<RC1, OV0>(uint32_t opcode);
template void dppc_interpreter::power_div<RC1, OV1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_div<RC0, OV0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_div<RC0, OV1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_div<RC1, OV0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_div<RC1, OV1>(uint32_t opcode);
template <field_rc rec, field_ov ov>
void dppc_interpreter::power_divs(uint32_t opcode) {
uint32_t dppc_interpreter::power_divs(uint32_t opcode) {
uint32_t ppc_result_d;
int32_t remainder;
ppc_grab_regsdab(opcode);
@ -157,15 +160,16 @@ void dppc_interpreter::power_divs(uint32_t opcode) {
ppc_store_iresult_reg(reg_d, ppc_result_d);
ppc_state.spr[SPR::MQ] = remainder;
return 0;
}
template void dppc_interpreter::power_divs<RC0, OV0>(uint32_t opcode);
template void dppc_interpreter::power_divs<RC0, OV1>(uint32_t opcode);
template void dppc_interpreter::power_divs<RC1, OV0>(uint32_t opcode);
template void dppc_interpreter::power_divs<RC1, OV1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_divs<RC0, OV0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_divs<RC0, OV1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_divs<RC1, OV0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_divs<RC1, OV1>(uint32_t opcode);
template <field_rc rec, field_ov ov>
void dppc_interpreter::power_doz(uint32_t opcode) {
uint32_t dppc_interpreter::power_doz(uint32_t opcode) {
ppc_grab_regsdab(opcode);
uint32_t ppc_result_d = (int32_t(ppc_result_a) < int32_t(ppc_result_b)) ?
ppc_result_b - ppc_result_a : 0;
@ -181,14 +185,15 @@ void dppc_interpreter::power_doz(uint32_t opcode) {
ppc_changecrf0(ppc_result_d);
ppc_store_iresult_reg(reg_d, ppc_result_d);
return 0;
}
template void dppc_interpreter::power_doz<RC0, OV0>(uint32_t opcode);
template void dppc_interpreter::power_doz<RC0, OV1>(uint32_t opcode);
template void dppc_interpreter::power_doz<RC1, OV0>(uint32_t opcode);
template void dppc_interpreter::power_doz<RC1, OV1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_doz<RC0, OV0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_doz<RC0, OV1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_doz<RC1, OV0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_doz<RC1, OV1>(uint32_t opcode);
void dppc_interpreter::power_dozi(uint32_t opcode) {
uint32_t dppc_interpreter::power_dozi(uint32_t opcode) {
uint32_t ppc_result_d;
ppc_grab_regsdasimm(opcode);
if (((int32_t)ppc_result_a) > simm) {
@ -197,10 +202,11 @@ void dppc_interpreter::power_dozi(uint32_t opcode) {
ppc_result_d = simm - ppc_result_a;
}
ppc_store_iresult_reg(reg_d, ppc_result_d);
return 0;
}
template <field_rc rec>
void dppc_interpreter::power_lscbx(uint32_t opcode) {
uint32_t dppc_interpreter::power_lscbx(uint32_t opcode) {
ppc_grab_regsdab(opcode);
uint32_t ea = ppc_result_b + (reg_a ? ppc_result_a : 0);
@ -248,13 +254,15 @@ void dppc_interpreter::power_lscbx(uint32_t opcode) {
(is_match ? CRx_bit::CR_EQ : 0) |
((ppc_state.spr[SPR::XER] & XER::SO) >> 3);
}
return 0;
}
template void dppc_interpreter::power_lscbx<RC0>(uint32_t opcode);
template void dppc_interpreter::power_lscbx<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_lscbx<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_lscbx<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::power_maskg(uint32_t opcode) {
uint32_t dppc_interpreter::power_maskg(uint32_t opcode) {
ppc_grab_regssab(opcode);
uint32_t mask_start = ppc_result_d & 0x1F;
uint32_t mask_end = ppc_result_b & 0x1F;
@ -276,13 +284,14 @@ void dppc_interpreter::power_maskg(uint32_t opcode) {
ppc_changecrf0(ppc_result_a);
ppc_store_iresult_reg(reg_a, ppc_result_a);
return 0;
}
template void dppc_interpreter::power_maskg<RC0>(uint32_t opcode);
template void dppc_interpreter::power_maskg<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_maskg<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_maskg<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::power_maskir(uint32_t opcode) {
uint32_t dppc_interpreter::power_maskir(uint32_t opcode) {
ppc_grab_regssab(opcode);
ppc_result_a = (ppc_result_a & ~ppc_result_b) | (ppc_result_d & ppc_result_b);
@ -290,13 +299,14 @@ void dppc_interpreter::power_maskir(uint32_t opcode) {
ppc_changecrf0(ppc_result_a);
ppc_store_iresult_reg(reg_a, ppc_result_a);
return 0;
}
template void dppc_interpreter::power_maskir<RC0>(uint32_t opcode);
template void dppc_interpreter::power_maskir<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_maskir<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_maskir<RC1>(uint32_t opcode);
template <field_rc rec, field_ov ov>
void dppc_interpreter::power_mul(uint32_t opcode) {
uint32_t dppc_interpreter::power_mul(uint32_t opcode) {
ppc_grab_regsdab(opcode);
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);
@ -311,16 +321,18 @@ void dppc_interpreter::power_mul(uint32_t opcode) {
}
if (rec)
ppc_changecrf0(uint32_t(product));
ppc_store_iresult_reg(reg_d, ppc_result_d);
return 0;
}
template void dppc_interpreter::power_mul<RC0, OV0>(uint32_t opcode);
template void dppc_interpreter::power_mul<RC0, OV1>(uint32_t opcode);
template void dppc_interpreter::power_mul<RC1, OV0>(uint32_t opcode);
template void dppc_interpreter::power_mul<RC1, OV1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_mul<RC0, OV0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_mul<RC0, OV1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_mul<RC1, OV0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_mul<RC1, OV1>(uint32_t opcode);
template <field_rc rec, field_ov ov>
void dppc_interpreter::power_nabs(uint32_t opcode) {
uint32_t dppc_interpreter::power_nabs(uint32_t opcode) {
ppc_grab_regsda(opcode);
uint32_t ppc_result_d = (int32_t(ppc_result_a) < 0) ? ppc_result_a : -ppc_result_a;
@ -330,14 +342,15 @@ void dppc_interpreter::power_nabs(uint32_t opcode) {
ppc_changecrf0(ppc_result_d);
ppc_store_iresult_reg(reg_d, ppc_result_d);
return 0;
}
template void dppc_interpreter::power_nabs<RC0, OV0>(uint32_t opcode);
template void dppc_interpreter::power_nabs<RC0, OV1>(uint32_t opcode);
template void dppc_interpreter::power_nabs<RC1, OV0>(uint32_t opcode);
template void dppc_interpreter::power_nabs<RC1, OV1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_nabs<RC0, OV0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_nabs<RC0, OV1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_nabs<RC1, OV0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_nabs<RC1, OV1>(uint32_t opcode);
void dppc_interpreter::power_rlmi(uint32_t opcode) {
uint32_t dppc_interpreter::power_rlmi(uint32_t opcode) {
ppc_grab_regssab(opcode);
unsigned rot_mb = (opcode >> 6) & 0x1F;
unsigned rot_me = (opcode >> 1) & 0x1F;
@ -352,10 +365,11 @@ void dppc_interpreter::power_rlmi(uint32_t opcode) {
ppc_changecrf0(ppc_result_a);
ppc_store_iresult_reg(reg_a, ppc_result_a);
return 0;
}
template <field_rc rec>
void dppc_interpreter::power_rrib(uint32_t opcode) {
uint32_t dppc_interpreter::power_rrib(uint32_t opcode) {
ppc_grab_regssab(opcode);
unsigned rot_sh = ppc_result_b & 0x1F;
@ -369,13 +383,14 @@ void dppc_interpreter::power_rrib(uint32_t opcode) {
ppc_changecrf0(ppc_result_a);
ppc_store_iresult_reg(reg_a, ppc_result_a);
return 0;
}
template void dppc_interpreter::power_rrib<RC0>(uint32_t opcode);
template void dppc_interpreter::power_rrib<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_rrib<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_rrib<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::power_sle(uint32_t opcode) {
uint32_t dppc_interpreter::power_sle(uint32_t opcode) {
ppc_grab_regssab(opcode);
unsigned rot_sh = ppc_result_b & 0x1F;
@ -388,13 +403,14 @@ void dppc_interpreter::power_sle(uint32_t opcode) {
ppc_changecrf0(ppc_result_a);
ppc_store_iresult_reg(reg_a, ppc_result_a);
return 0;
}
template void dppc_interpreter::power_sle<RC0>(uint32_t opcode);
template void dppc_interpreter::power_sle<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_sle<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_sle<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::power_sleq(uint32_t opcode) {
uint32_t dppc_interpreter::power_sleq(uint32_t opcode) {
ppc_grab_regssab(opcode);
unsigned rot_sh = ppc_result_b & 0x1F;
uint32_t r = rot_sh ? ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh))) : ppc_result_d;
@ -407,13 +423,14 @@ void dppc_interpreter::power_sleq(uint32_t opcode) {
ppc_changecrf0(ppc_result_a);
ppc_store_iresult_reg(reg_a, ppc_result_a);
return 0;
}
template void dppc_interpreter::power_sleq<RC0>(uint32_t opcode);
template void dppc_interpreter::power_sleq<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_sleq<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_sleq<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::power_sliq(uint32_t opcode) {
uint32_t dppc_interpreter::power_sliq(uint32_t opcode) {
ppc_grab_regssash(opcode);
ppc_result_a = ppc_result_d << rot_sh;
@ -423,13 +440,14 @@ void dppc_interpreter::power_sliq(uint32_t opcode) {
ppc_changecrf0(ppc_result_a);
ppc_store_iresult_reg(reg_a, ppc_result_a);
return 0;
}
template void dppc_interpreter::power_sliq<RC0>(uint32_t opcode);
template void dppc_interpreter::power_sliq<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_sliq<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_sliq<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::power_slliq(uint32_t opcode) {
uint32_t dppc_interpreter::power_slliq(uint32_t opcode) {
ppc_grab_regssash(opcode);
uint32_t r = rot_sh ? ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh))) : ppc_result_d;
uint32_t mask = power_rot_mask(0, 31 - rot_sh);
@ -441,13 +459,14 @@ void dppc_interpreter::power_slliq(uint32_t opcode) {
ppc_changecrf0(ppc_result_a);
ppc_store_iresult_reg(reg_a, ppc_result_a);
return 0;
}
template void dppc_interpreter::power_slliq<RC0>(uint32_t opcode);
template void dppc_interpreter::power_slliq<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_slliq<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_slliq<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::power_sllq(uint32_t opcode) {
uint32_t dppc_interpreter::power_sllq(uint32_t opcode) {
ppc_grab_regssab(opcode);
unsigned rot_sh = ppc_result_b & 0x1F;
@ -461,13 +480,14 @@ void dppc_interpreter::power_sllq(uint32_t opcode) {
ppc_changecrf0(ppc_result_a);
ppc_store_iresult_reg(reg_a, ppc_result_a);
return 0;
}
template void dppc_interpreter::power_sllq<RC0>(uint32_t opcode);
template void dppc_interpreter::power_sllq<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_sllq<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_sllq<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::power_slq(uint32_t opcode) {
uint32_t dppc_interpreter::power_slq(uint32_t opcode) {
ppc_grab_regssab(opcode);
unsigned rot_sh = ppc_result_b & 0x1F;
@ -482,13 +502,14 @@ void dppc_interpreter::power_slq(uint32_t opcode) {
ppc_state.spr[SPR::MQ] = rot_sh ? ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh))) : ppc_result_d;
ppc_store_iresult_reg(reg_a, ppc_result_a);
return 0;
}
template void dppc_interpreter::power_slq<RC0>(uint32_t opcode);
template void dppc_interpreter::power_slq<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_slq<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_slq<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::power_sraiq(uint32_t opcode) {
uint32_t dppc_interpreter::power_sraiq(uint32_t opcode) {
ppc_grab_regssash(opcode);
uint32_t mask = (1U << rot_sh) - 1;
ppc_result_a = (int32_t)ppc_result_d >> rot_sh;
@ -504,13 +525,14 @@ void dppc_interpreter::power_sraiq(uint32_t opcode) {
ppc_changecrf0(ppc_result_a);
ppc_store_iresult_reg(reg_a, ppc_result_a);
return 0;
}
template void dppc_interpreter::power_sraiq<RC0>(uint32_t opcode);
template void dppc_interpreter::power_sraiq<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_sraiq<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_sraiq<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::power_sraq(uint32_t opcode) {
uint32_t dppc_interpreter::power_sraq(uint32_t opcode) {
ppc_grab_regssab(opcode);
unsigned rot_sh = ppc_result_b & 0x1F;
uint32_t mask = (ppc_result_b & 0x20) ? -1 : (1U << rot_sh) - 1;
@ -529,13 +551,14 @@ void dppc_interpreter::power_sraq(uint32_t opcode) {
ppc_changecrf0(ppc_result_a);
ppc_store_iresult_reg(reg_a, ppc_result_a);
return 0;
}
template void dppc_interpreter::power_sraq<RC0>(uint32_t opcode);
template void dppc_interpreter::power_sraq<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_sraq<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_sraq<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::power_sre(uint32_t opcode) {
uint32_t dppc_interpreter::power_sre(uint32_t opcode) {
ppc_grab_regssab(opcode);
unsigned rot_sh = ppc_result_b & 0x1F;
@ -547,13 +570,14 @@ void dppc_interpreter::power_sre(uint32_t opcode) {
ppc_changecrf0(ppc_result_a);
ppc_store_iresult_reg(reg_a, ppc_result_a);
return 0;
}
template void dppc_interpreter::power_sre<RC0>(uint32_t opcode);
template void dppc_interpreter::power_sre<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_sre<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_sre<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::power_srea(uint32_t opcode) {
uint32_t dppc_interpreter::power_srea(uint32_t opcode) {
ppc_grab_regssab(opcode);
unsigned rot_sh = ppc_result_b & 0x1F;
ppc_result_a = (int32_t)ppc_result_d >> rot_sh;
@ -571,13 +595,14 @@ void dppc_interpreter::power_srea(uint32_t opcode) {
ppc_store_iresult_reg(reg_a, ppc_result_a);
ppc_state.spr[SPR::MQ] = r;
return 0;
}
template void dppc_interpreter::power_srea<RC0>(uint32_t opcode);
template void dppc_interpreter::power_srea<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_srea<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_srea<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::power_sreq(uint32_t opcode) {
uint32_t dppc_interpreter::power_sreq(uint32_t opcode) {
ppc_grab_regssab(opcode);
unsigned rot_sh = ppc_result_b & 0x1F;
uint32_t mask = -1U >> rot_sh;
@ -589,13 +614,14 @@ void dppc_interpreter::power_sreq(uint32_t opcode) {
ppc_changecrf0(ppc_result_a);
ppc_store_iresult_reg(reg_a, ppc_result_a);
return 0;
}
template void dppc_interpreter::power_sreq<RC0>(uint32_t opcode);
template void dppc_interpreter::power_sreq<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_sreq<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_sreq<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::power_sriq(uint32_t opcode) {
uint32_t dppc_interpreter::power_sriq(uint32_t opcode) {
ppc_grab_regssash(opcode);
ppc_result_a = ppc_result_d >> rot_sh;
ppc_state.spr[SPR::MQ] = rot_sh ? ((ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh))) : ppc_result_d;
@ -604,13 +630,14 @@ void dppc_interpreter::power_sriq(uint32_t opcode) {
ppc_changecrf0(ppc_result_a);
ppc_store_iresult_reg(reg_a, ppc_result_a);
return 0;
}
template void dppc_interpreter::power_sriq<RC0>(uint32_t opcode);
template void dppc_interpreter::power_sriq<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_sriq<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_sriq<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::power_srliq(uint32_t opcode) {
uint32_t dppc_interpreter::power_srliq(uint32_t opcode) {
ppc_grab_regssash(opcode);
uint32_t r = rot_sh ? ((ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh))) : ppc_result_d;
unsigned mask = power_rot_mask(rot_sh, 31);
@ -622,13 +649,14 @@ void dppc_interpreter::power_srliq(uint32_t opcode) {
ppc_changecrf0(ppc_result_a);
ppc_store_iresult_reg(reg_a, ppc_result_a);
return 0;
}
template void dppc_interpreter::power_srliq<RC0>(uint32_t opcode);
template void dppc_interpreter::power_srliq<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_srliq<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_srliq<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::power_srlq(uint32_t opcode) {
uint32_t dppc_interpreter::power_srlq(uint32_t opcode) {
ppc_grab_regssab(opcode);
unsigned rot_sh = ppc_result_b & 0x1F;
uint32_t r = rot_sh ? ((ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh))) : ppc_result_d;
@ -644,13 +672,14 @@ void dppc_interpreter::power_srlq(uint32_t opcode) {
ppc_changecrf0(ppc_result_a);
ppc_store_iresult_reg(reg_a, ppc_result_a);
return 0;
}
template void dppc_interpreter::power_srlq<RC0>(uint32_t opcode);
template void dppc_interpreter::power_srlq<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_srlq<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_srlq<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::power_srq(uint32_t opcode) {
uint32_t dppc_interpreter::power_srq(uint32_t opcode) {
ppc_grab_regssab(opcode);
unsigned rot_sh = ppc_result_b & 0x1F;
@ -666,7 +695,8 @@ void dppc_interpreter::power_srq(uint32_t opcode) {
ppc_changecrf0(ppc_result_a);
ppc_store_iresult_reg(reg_a, ppc_result_a);
return 0;
}
template void dppc_interpreter::power_srq<RC0>(uint32_t opcode);
template void dppc_interpreter::power_srq<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::power_srq<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::power_srq<RC1>(uint32_t opcode);

View File

@ -47,7 +47,7 @@ enum EXEC_MODE:uint32_t {
enum endian_switch { big_end = 0, little_end = 1 };
typedef void (*PPCOpcode)(uint32_t opcode);
typedef uint32_t (*PPCOpcode)(uint32_t opcode);
union FPR_storage {
double dbl64_r; // double floating-point representation
@ -299,8 +299,6 @@ enum Exc_Cause : uint32_t {
TRAP = 1 << (31 - 14),
};
extern unsigned exec_flags;
extern jmp_buf exc_env;
enum Po_Cause : int {
@ -419,8 +417,9 @@ void set_host_rounding_mode(uint8_t mode);
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);
uint32_t ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits, uint32_t exec_flags);
[[noreturn]] uint32_t dbg_exception_handler(
Except_Type exception_type, uint32_t srr1_bits, uint32_t exec_flags);
void ppc_floating_point_exception(uint32_t opcode);
void ppc_alignment_exception(uint32_t opcode, uint32_t ea);
@ -433,203 +432,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(uint32_t opcode);
template <field_lk l> extern void ppc_bclr(uint32_t opcode);
extern void ppc_crand(uint32_t opcode);
extern void ppc_crandc(uint32_t opcode);
extern void ppc_creqv(uint32_t opcode);
extern void ppc_crnand(uint32_t opcode);
extern void ppc_crnor(uint32_t opcode);
extern void ppc_cror(uint32_t opcode);
extern void ppc_crorc(uint32_t opcode);
extern void ppc_crxor(uint32_t opcode);
extern void ppc_isync(uint32_t opcode);
template <field_lk l, field_601 for601> extern uint32_t ppc_bcctr(uint32_t opcode);
template <field_lk l> extern uint32_t ppc_bclr(uint32_t opcode);
extern uint32_t ppc_crand(uint32_t opcode);
extern uint32_t ppc_crandc(uint32_t opcode);
extern uint32_t ppc_creqv(uint32_t opcode);
extern uint32_t ppc_crnand(uint32_t opcode);
extern uint32_t ppc_crnor(uint32_t opcode);
extern uint32_t ppc_cror(uint32_t opcode);
extern uint32_t ppc_crorc(uint32_t opcode);
extern uint32_t ppc_crxor(uint32_t opcode);
extern uint32_t ppc_isync(uint32_t opcode);
template <logical_fun logical_op, field_rc rec> extern void ppc_logical(uint32_t opcode);
template <logical_fun logical_op, field_rc rec> extern uint32_t ppc_logical(uint32_t opcode);
template <field_carry carry, field_rc rec, field_ov ov> extern void ppc_add(uint32_t opcode);
template <field_rc rec, field_ov ov> extern void ppc_adde(uint32_t opcode);
template <field_rc rec, field_ov ov> extern void ppc_addme(uint32_t opcode);
template <field_rc rec, field_ov ov> extern void ppc_addze(uint32_t opcode);
extern void ppc_cmp(uint32_t opcode);
extern void ppc_cmpl(uint32_t opcode);
template <field_rc rec> extern void ppc_cntlzw(uint32_t opcode);
extern void ppc_dcbf(uint32_t opcode);
extern void ppc_dcbi(uint32_t opcode);
extern void ppc_dcbst(uint32_t opcode);
extern void ppc_dcbt(uint32_t opcode);
extern void ppc_dcbtst(uint32_t opcode);
extern void ppc_dcbz(uint32_t opcode);
template <field_rc rec, field_ov ov> extern void ppc_divw(uint32_t opcode);
template <field_rc rec, field_ov ov> extern void ppc_divwu(uint32_t opcode);
extern void ppc_eciwx(uint32_t opcode);
extern void ppc_ecowx(uint32_t opcode);
extern void ppc_eieio(uint32_t opcode);
template <class T, field_rc rec>extern void ppc_exts(uint32_t opcode);
extern void ppc_icbi(uint32_t opcode);
extern void ppc_mftb(uint32_t opcode);
extern void ppc_lhaux(uint32_t opcode);
extern void ppc_lhax(uint32_t opcode);
extern void ppc_lhbrx(uint32_t opcode);
extern void ppc_lwarx(uint32_t opcode);
extern void ppc_lwbrx(uint32_t opcode);
template <class T> extern void ppc_lzx(uint32_t opcode);
template <class T> extern void ppc_lzux(uint32_t opcode);
extern void ppc_mcrxr(uint32_t opcode);
extern void ppc_mfcr(uint32_t opcode);
template <field_rc rec> extern void ppc_mulhwu(uint32_t opcode);
template <field_rc rec> extern void ppc_mulhw(uint32_t opcode);
template <field_rc rec, field_ov ov> extern void ppc_mullw(uint32_t opcode);
template <field_rc rec, field_ov ov> extern void ppc_neg(uint32_t opcode);
template <field_direction shift, field_rc rec> extern void ppc_shift(uint32_t opcode);
template <field_rc rec> extern void ppc_sraw(uint32_t opcode);
template <field_rc rec> extern void ppc_srawi(uint32_t opcode);
template <class T> extern void ppc_stx(uint32_t opcode);
template <class T> extern void ppc_stux(uint32_t opcode);
extern void ppc_stfiwx(uint32_t opcode);
extern void ppc_sthbrx(uint32_t opcode);
extern void ppc_stwcx(uint32_t opcode);
extern void ppc_stwbrx(uint32_t opcode);
template <field_carry carry, field_rc rec, field_ov ov> extern void ppc_subf(uint32_t opcode);
template <field_rc rec, field_ov ov> extern void ppc_subfe(uint32_t opcode);
template <field_rc rec, field_ov ov> extern void ppc_subfme(uint32_t opcode);
template <field_rc rec, field_ov ov> extern void ppc_subfze(uint32_t opcode);
extern void ppc_sync(uint32_t opcode);
extern void ppc_tlbia(uint32_t opcode);
extern void ppc_tlbie(uint32_t opcode);
extern void ppc_tlbli(uint32_t opcode);
extern void ppc_tlbld(uint32_t opcode);
extern void ppc_tlbsync(uint32_t opcode);
extern void ppc_tw(uint32_t opcode);
template <field_carry carry, field_rc rec, field_ov ov> extern uint32_t ppc_add(uint32_t opcode);
template <field_rc rec, field_ov ov> extern uint32_t ppc_adde(uint32_t opcode);
template <field_rc rec, field_ov ov> extern uint32_t ppc_addme(uint32_t opcode);
template <field_rc rec, field_ov ov> extern uint32_t ppc_addze(uint32_t opcode);
extern uint32_t ppc_cmp(uint32_t opcode);
extern uint32_t ppc_cmpl(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_cntlzw(uint32_t opcode);
extern uint32_t ppc_dcbf(uint32_t opcode);
extern uint32_t ppc_dcbi(uint32_t opcode);
extern uint32_t ppc_dcbst(uint32_t opcode);
extern uint32_t ppc_dcbt(uint32_t opcode);
extern uint32_t ppc_dcbtst(uint32_t opcode);
extern uint32_t ppc_dcbz(uint32_t opcode);
template <field_rc rec, field_ov ov> extern uint32_t ppc_divw(uint32_t opcode);
template <field_rc rec, field_ov ov> extern uint32_t ppc_divwu(uint32_t opcode);
extern uint32_t ppc_eciwx(uint32_t opcode);
extern uint32_t ppc_ecowx(uint32_t opcode);
extern uint32_t ppc_eieio(uint32_t opcode);
template <class T, field_rc rec>extern uint32_t ppc_exts(uint32_t opcode);
extern uint32_t ppc_icbi(uint32_t opcode);
extern uint32_t ppc_mftb(uint32_t opcode);
extern uint32_t ppc_lhaux(uint32_t opcode);
extern uint32_t ppc_lhax(uint32_t opcode);
extern uint32_t ppc_lhbrx(uint32_t opcode);
extern uint32_t ppc_lwarx(uint32_t opcode);
extern uint32_t ppc_lwbrx(uint32_t opcode);
template <class T> extern uint32_t ppc_lzx(uint32_t opcode);
template <class T> extern uint32_t ppc_lzux(uint32_t opcode);
extern uint32_t ppc_mcrxr(uint32_t opcode);
extern uint32_t ppc_mfcr(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_mulhwu(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_mulhw(uint32_t opcode);
template <field_rc rec, field_ov ov> extern uint32_t ppc_mullw(uint32_t opcode);
template <field_rc rec, field_ov ov> extern uint32_t ppc_neg(uint32_t opcode);
template <field_direction shift, field_rc rec> extern uint32_t ppc_shift(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_sraw(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_srawi(uint32_t opcode);
template <class T> extern uint32_t ppc_stx(uint32_t opcode);
template <class T> extern uint32_t ppc_stux(uint32_t opcode);
extern uint32_t ppc_stfiwx(uint32_t opcode);
extern uint32_t ppc_sthbrx(uint32_t opcode);
extern uint32_t ppc_stwcx(uint32_t opcode);
extern uint32_t ppc_stwbrx(uint32_t opcode);
template <field_carry carry, field_rc rec, field_ov ov> extern uint32_t ppc_subf(uint32_t opcode);
template <field_rc rec, field_ov ov> extern uint32_t ppc_subfe(uint32_t opcode);
template <field_rc rec, field_ov ov> extern uint32_t ppc_subfme(uint32_t opcode);
template <field_rc rec, field_ov ov> extern uint32_t ppc_subfze(uint32_t opcode);
extern uint32_t ppc_sync(uint32_t opcode);
extern uint32_t ppc_tlbia(uint32_t opcode);
extern uint32_t ppc_tlbie(uint32_t opcode);
extern uint32_t ppc_tlbli(uint32_t opcode);
extern uint32_t ppc_tlbld(uint32_t opcode);
extern uint32_t ppc_tlbsync(uint32_t opcode);
extern uint32_t ppc_tw(uint32_t opcode);
extern void ppc_lswi(uint32_t opcode);
extern void ppc_lswx(uint32_t opcode);
extern void ppc_stswi(uint32_t opcode);
extern void ppc_stswx(uint32_t opcode);
extern uint32_t ppc_lswi(uint32_t opcode);
extern uint32_t ppc_lswx(uint32_t opcode);
extern uint32_t ppc_stswi(uint32_t opcode);
extern uint32_t ppc_stswx(uint32_t opcode);
extern void ppc_mfsr(uint32_t opcode);
extern void ppc_mfsrin(uint32_t opcode);
extern void ppc_mtsr(uint32_t opcode);
extern void ppc_mtsrin(uint32_t opcode);
extern uint32_t ppc_mfsr(uint32_t opcode);
extern uint32_t ppc_mfsrin(uint32_t opcode);
extern uint32_t ppc_mtsr(uint32_t opcode);
extern uint32_t ppc_mtsrin(uint32_t opcode);
extern void ppc_mcrf(uint32_t opcode);
extern void ppc_mtcrf(uint32_t opcode);
extern void ppc_mfmsr(uint32_t opcode);
extern void ppc_mfspr(uint32_t opcode);
extern void ppc_mtmsr(uint32_t opcode);
extern void ppc_mtspr(uint32_t opcode);
extern uint32_t ppc_mcrf(uint32_t opcode);
extern uint32_t ppc_mtcrf(uint32_t opcode);
extern uint32_t ppc_mfmsr(uint32_t opcode);
extern uint32_t ppc_mfspr(uint32_t opcode);
extern uint32_t ppc_mtmsr(uint32_t opcode);
extern uint32_t ppc_mtspr(uint32_t opcode);
template <field_rc rec> extern void ppc_mtfsb0(uint32_t opcode);
template <field_rc rec> extern void ppc_mtfsb1(uint32_t opcode);
extern void ppc_mcrfs(uint32_t opcode);
template <field_rc rec> extern void ppc_fmr(uint32_t opcode);
template <field_601 for601, field_rc rec> extern void ppc_mffs(uint32_t opcode);
template <field_rc rec> extern void ppc_mtfsf(uint32_t opcode);
template <field_rc rec> extern void ppc_mtfsfi(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_mtfsb0(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_mtfsb1(uint32_t opcode);
extern uint32_t ppc_mcrfs(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fmr(uint32_t opcode);
template <field_601 for601, field_rc rec> extern uint32_t ppc_mffs(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_mtfsf(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_mtfsfi(uint32_t opcode);
template <field_shift shift> extern void ppc_addi(uint32_t opcode);
template <field_rc rec> extern void ppc_addic(uint32_t opcode);
template <field_shift shift> extern void ppc_andirc(uint32_t opcode);
template <field_lk l, field_aa a> extern void ppc_b(uint32_t opcode);
template <field_lk l, field_aa a> extern void ppc_bc(uint32_t opcode);
extern void ppc_cmpi(uint32_t opcode);
extern void ppc_cmpli(uint32_t opcode);
template <class T> extern void ppc_lz(uint32_t opcode);
template <class T> extern void ppc_lzu(uint32_t opcode);
extern void ppc_lha(uint32_t opcode);
extern void ppc_lhau(uint32_t opcode);
extern void ppc_lmw(uint32_t opcode);
extern void ppc_mulli(uint32_t opcode);
template <field_shift shift> extern void ppc_ori(uint32_t opcode);
extern void ppc_rfi(uint32_t opcode);
extern void ppc_rlwimi(uint32_t opcode);
extern void ppc_rlwinm(uint32_t opcode);
extern void ppc_rlwnm(uint32_t opcode);
extern void ppc_sc(uint32_t opcode);
template <class T> extern void ppc_st(uint32_t opcode);
template <class T> extern void ppc_stu(uint32_t opcode);
extern void ppc_stmw(uint32_t opcode);
extern void ppc_subfic(uint32_t opcode);
extern void ppc_twi(uint32_t opcode);
template <field_shift shift> extern void ppc_xori(uint32_t opcode);
template <field_shift shift> extern uint32_t ppc_addi(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_addic(uint32_t opcode);
template <field_shift shift> extern uint32_t ppc_andirc(uint32_t opcode);
template <field_lk l, field_aa a> extern uint32_t ppc_b(uint32_t opcode);
template <field_lk l, field_aa a> extern uint32_t ppc_bc(uint32_t opcode);
extern uint32_t ppc_cmpi(uint32_t opcode);
extern uint32_t ppc_cmpli(uint32_t opcode);
template <class T> extern uint32_t ppc_lz(uint32_t opcode);
template <class T> extern uint32_t ppc_lzu(uint32_t opcode);
extern uint32_t ppc_lha(uint32_t opcode);
extern uint32_t ppc_lhau(uint32_t opcode);
extern uint32_t ppc_lmw(uint32_t opcode);
extern uint32_t ppc_mulli(uint32_t opcode);
template <field_shift shift> extern uint32_t ppc_ori(uint32_t opcode);
extern uint32_t ppc_rfi(uint32_t opcode);
extern uint32_t ppc_rlwimi(uint32_t opcode);
extern uint32_t ppc_rlwinm(uint32_t opcode);
extern uint32_t ppc_rlwnm(uint32_t opcode);
extern uint32_t ppc_sc(uint32_t opcode);
template <class T> extern uint32_t ppc_st(uint32_t opcode);
template <class T> extern uint32_t ppc_stu(uint32_t opcode);
extern uint32_t ppc_stmw(uint32_t opcode);
extern uint32_t ppc_subfic(uint32_t opcode);
extern uint32_t ppc_twi(uint32_t opcode);
template <field_shift shift> extern uint32_t ppc_xori(uint32_t opcode);
extern void ppc_lfs(uint32_t opcode);
extern void ppc_lfsu(uint32_t opcode);
extern void ppc_lfsx(uint32_t opcode);
extern void ppc_lfsux(uint32_t opcode);
extern void ppc_lfd(uint32_t opcode);
extern void ppc_lfdu(uint32_t opcode);
extern void ppc_lfdx(uint32_t opcode);
extern void ppc_lfdux(uint32_t opcode);
extern void ppc_stfs(uint32_t opcode);
extern void ppc_stfsu(uint32_t opcode);
extern void ppc_stfsx(uint32_t opcode);
extern void ppc_stfsux(uint32_t opcode);
extern void ppc_stfd(uint32_t opcode);
extern void ppc_stfdu(uint32_t opcode);
extern void ppc_stfdx(uint32_t opcode);
extern void ppc_stfdux(uint32_t opcode);
extern uint32_t ppc_lfs(uint32_t opcode);
extern uint32_t ppc_lfsu(uint32_t opcode);
extern uint32_t ppc_lfsx(uint32_t opcode);
extern uint32_t ppc_lfsux(uint32_t opcode);
extern uint32_t ppc_lfd(uint32_t opcode);
extern uint32_t ppc_lfdu(uint32_t opcode);
extern uint32_t ppc_lfdx(uint32_t opcode);
extern uint32_t ppc_lfdux(uint32_t opcode);
extern uint32_t ppc_stfs(uint32_t opcode);
extern uint32_t ppc_stfsu(uint32_t opcode);
extern uint32_t ppc_stfsx(uint32_t opcode);
extern uint32_t ppc_stfsux(uint32_t opcode);
extern uint32_t ppc_stfd(uint32_t opcode);
extern uint32_t ppc_stfdu(uint32_t opcode);
extern uint32_t ppc_stfdx(uint32_t opcode);
extern uint32_t ppc_stfdux(uint32_t opcode);
template <field_rc rec> extern void ppc_fadd(uint32_t opcode);
template <field_rc rec> extern void ppc_fsub(uint32_t opcode);
template <field_rc rec> extern void ppc_fmul(uint32_t opcode);
template <field_rc rec> extern void ppc_fdiv(uint32_t opcode);
template <field_rc rec> extern void ppc_fadds(uint32_t opcode);
template <field_rc rec> extern void ppc_fsubs(uint32_t opcode);
template <field_rc rec> extern void ppc_fmuls(uint32_t opcode);
template <field_rc rec> extern void ppc_fdivs(uint32_t opcode);
template <field_rc rec> extern void ppc_fmadd(uint32_t opcode);
template <field_rc rec> extern void ppc_fmsub(uint32_t opcode);
template <field_rc rec> extern void ppc_fnmadd(uint32_t opcode);
template <field_rc rec> extern void ppc_fnmsub(uint32_t opcode);
template <field_rc rec> extern void ppc_fmadds(uint32_t opcode);
template <field_rc rec> extern void ppc_fmsubs(uint32_t opcode);
template <field_rc rec> extern void ppc_fnmadds(uint32_t opcode);
template <field_rc rec> extern void ppc_fnmsubs(uint32_t opcode);
template <field_rc rec> extern void ppc_fabs(uint32_t opcode);
template <field_rc rec> extern void ppc_fnabs(uint32_t opcode);
template <field_rc rec> extern void ppc_fneg(uint32_t opcode);
template <field_rc rec> extern void ppc_fsel(uint32_t opcode);
template <field_rc rec> extern void ppc_fres(uint32_t opcode);
template <field_rc rec> extern void ppc_fsqrts(uint32_t opcode);
template <field_rc rec> extern void ppc_fsqrt(uint32_t opcode);
template <field_rc rec> extern void ppc_frsqrte(uint32_t opcode);
template <field_rc rec> extern void ppc_frsp(uint32_t opcode);
template <field_rc rec> extern void ppc_fctiw(uint32_t opcode);
template <field_rc rec> extern void ppc_fctiwz(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fadd(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fsub(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fmul(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fdiv(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fadds(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fsubs(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fmuls(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fdivs(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fmadd(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fmsub(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fnmadd(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fnmsub(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fmadds(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fmsubs(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fnmadds(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fnmsubs(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fabs(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fnabs(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fneg(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fsel(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fres(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fsqrts(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fsqrt(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_frsqrte(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_frsp(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fctiw(uint32_t opcode);
template <field_rc rec> extern uint32_t ppc_fctiwz(uint32_t opcode);
extern void ppc_fcmpo(uint32_t opcode);
extern void ppc_fcmpu(uint32_t opcode);
extern uint32_t ppc_fcmpo(uint32_t opcode);
extern uint32_t ppc_fcmpu(uint32_t opcode);
// Power-specific instructions
template <field_rc rec, field_ov ov> extern void power_abs(uint32_t opcode);
extern void power_clcs(uint32_t opcode);
template <field_rc rec, field_ov ov> extern void power_div(uint32_t opcode);
template <field_rc rec, field_ov ov> extern void power_divs(uint32_t opcode);
template <field_rc rec, field_ov ov> extern void power_doz(uint32_t opcode);
extern void power_dozi(uint32_t opcode);
template <field_rc rec> extern void power_lscbx(uint32_t opcode);
template <field_rc rec> extern void power_maskg(uint32_t opcode);
template <field_rc rec> extern void power_maskir(uint32_t opcode);
template <field_rc rec, field_ov ov> extern void power_mul(uint32_t opcode);
template <field_rc rec, field_ov ov> extern void power_nabs(uint32_t opcode);
extern void power_rlmi(uint32_t opcode);
template <field_rc rec> extern void power_rrib(uint32_t opcode);
template <field_rc rec> extern void power_sle(uint32_t opcode);
template <field_rc rec> extern void power_sleq(uint32_t opcode);
template <field_rc rec> extern void power_sliq(uint32_t opcode);
template <field_rc rec> extern void power_slliq(uint32_t opcode);
template <field_rc rec> extern void power_sllq(uint32_t opcode);
template <field_rc rec> extern void power_slq(uint32_t opcode);
template <field_rc rec> extern void power_sraiq(uint32_t opcode);
template <field_rc rec> extern void power_sraq(uint32_t opcode);
template <field_rc rec> extern void power_sre(uint32_t opcode);
template <field_rc rec> extern void power_srea(uint32_t opcode);
template <field_rc rec> extern void power_sreq(uint32_t opcode);
template <field_rc rec> extern void power_sriq(uint32_t opcode);
template <field_rc rec> extern void power_srliq(uint32_t opcode);
template <field_rc rec> extern void power_srlq(uint32_t opcode);
template <field_rc rec> extern void power_srq(uint32_t opcode);
template <field_rc rec, field_ov ov> extern uint32_t power_abs(uint32_t opcode);
extern uint32_t power_clcs(uint32_t opcode);
template <field_rc rec, field_ov ov> extern uint32_t power_div(uint32_t opcode);
template <field_rc rec, field_ov ov> extern uint32_t power_divs(uint32_t opcode);
template <field_rc rec, field_ov ov> extern uint32_t power_doz(uint32_t opcode);
extern uint32_t power_dozi(uint32_t opcode);
template <field_rc rec> extern uint32_t power_lscbx(uint32_t opcode);
template <field_rc rec> extern uint32_t power_maskg(uint32_t opcode);
template <field_rc rec> extern uint32_t power_maskir(uint32_t opcode);
template <field_rc rec, field_ov ov> extern uint32_t power_mul(uint32_t opcode);
template <field_rc rec, field_ov ov> extern uint32_t power_nabs(uint32_t opcode);
extern uint32_t power_rlmi(uint32_t opcode);
template <field_rc rec> extern uint32_t power_rrib(uint32_t opcode);
template <field_rc rec> extern uint32_t power_sle(uint32_t opcode);
template <field_rc rec> extern uint32_t power_sleq(uint32_t opcode);
template <field_rc rec> extern uint32_t power_sliq(uint32_t opcode);
template <field_rc rec> extern uint32_t power_slliq(uint32_t opcode);
template <field_rc rec> extern uint32_t power_sllq(uint32_t opcode);
template <field_rc rec> extern uint32_t power_slq(uint32_t opcode);
template <field_rc rec> extern uint32_t power_sraiq(uint32_t opcode);
template <field_rc rec> extern uint32_t power_sraq(uint32_t opcode);
template <field_rc rec> extern uint32_t power_sre(uint32_t opcode);
template <field_rc rec> extern uint32_t power_srea(uint32_t opcode);
template <field_rc rec> extern uint32_t power_sreq(uint32_t opcode);
template <field_rc rec> extern uint32_t power_sriq(uint32_t opcode);
template <field_rc rec> extern uint32_t power_srliq(uint32_t opcode);
template <field_rc rec> extern uint32_t power_srlq(uint32_t opcode);
template <field_rc rec> extern uint32_t power_srq(uint32_t opcode);
} // namespace dppc_interpreter
// AltiVec instructions
@ -640,7 +639,7 @@ template <field_rc rec> extern void power_srq(uint32_t opcode);
extern uint64_t get_virt_time_ns(void);
extern void ppc_main_opcode(uint32_t opcode);
extern uint32_t ppc_main_opcode(uint32_t opcode);
extern void ppc_exec(void);
extern void ppc_exec_single(void);
extern void ppc_exec_until(uint32_t goal_addr);

View File

@ -32,7 +32,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
jmp_buf exc_env; /* Global exception environment. */
#if !defined(PPC_TESTS) && !defined(PPC_BENCHMARKS)
void ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits) {
uint32_t ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits, uint32_t exec_flags = 0) {
#ifdef CPU_PROFILING
exceptions_processed++;
#endif
@ -135,10 +135,12 @@ void ppc_exception_handler(Except_Type exception_type, uint32_t srr1_bits) {
if (exception_type != Except_Type::EXC_EXT_INT && exception_type != Except_Type::EXC_DECR) {
longjmp(exc_env, 2); /* return to the main execution loop. */
}
return exec_flags;
}
#endif
[[noreturn]] void dbg_exception_handler(Except_Type exception_type, uint32_t srr1_bits) {
[[noreturn]] uint32_t dbg_exception_handler(Except_Type exception_type, uint32_t srr1_bits, uint32_t exec_flags) {
std::string exc_descriptor;
switch (exception_type) {
@ -311,5 +313,5 @@ unexpected_instruction:
ppc_state.spr[SPR::DSISR] = dsisr;
ppc_state.spr[SPR::DAR] = ea;
ppc_exception_handler(Except_Type::EXC_ALIGNMENT, 0x0);
ppc_exception_handler(Except_Type::EXC_ALIGNMENT, 0x0, 0);
}

View File

@ -67,7 +67,6 @@ SetPRS ppc_state;
uint32_t ppc_next_instruction_address; // Used for branching, setting up the NIA
unsigned exec_flags; // execution control flags
// FIXME: exec_timer is read by main thread ppc_main_opcode;
// written by audio dbdma DMAChannel::update_irq .. add_immediate_timer
volatile bool exec_timer;
@ -187,14 +186,14 @@ static PPCOpcode OpcodeGrabber[64 * 2048];
/** Exception helpers. */
void ppc_illegalop(uint32_t opcode) {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP, 0);
}
void ppc_assert_int() {
int_pin = true;
if (ppc_state.msr & MSR::EE) {
LOG_F(5, "CPU ExtIntHandler called");
ppc_exception_handler(Except_Type::EXC_EXT_INT, 0);
ppc_exception_handler(Except_Type::EXC_EXT_INT, 0, 0);
} else {
LOG_F(5, "CPU IRQ ignored!");
}
@ -207,7 +206,7 @@ void ppc_release_int() {
/** Opcode decoding functions. */
/* Dispatch using primary and modifier opcode */
void ppc_main_opcode(uint32_t opcode)
uint32_t ppc_main_opcode(uint32_t opcode)
{
#ifdef CPU_PROFILING
num_executed_instrs++;
@ -215,7 +214,7 @@ void ppc_main_opcode(uint32_t opcode)
num_opcodes[opcode]++;
#endif
#endif
OpcodeGrabber[(opcode >> 15 & 0x1F800) | (opcode & 0x7FF)](opcode);
return OpcodeGrabber[(opcode >> 15 & 0x1F800) | (opcode & 0x7FF)](opcode);
}
static long long cpu_now_ns() {
@ -267,6 +266,7 @@ static void ppc_exec_inner(uint32_t start_addr, uint32_t size)
uint64_t max_cycles = 0;
uint32_t page_start, eb_start, eb_end = 0;
uint32_t opcode;
uint32_t exec_flags; // execution control flags
uint8_t* pc_real;
while (power_on) {
@ -285,7 +285,7 @@ static void ppc_exec_inner(uint32_t start_addr, uint32_t size)
}
opcode = ppc_read_instruction(pc_real);
ppc_main_opcode(opcode);
exec_flags = ppc_main_opcode(opcode);
if (g_icycles++ >= max_cycles || exec_timer)
max_cycles = process_events();
@ -334,17 +334,18 @@ void ppc_exec()
/** Execute one PPC instruction. */
void ppc_exec_single()
{
uint32_t exec_flags = 0;
if (setjmp(exc_env)) {
// process low-level exceptions
//LOG_F(9, "PPC-EXEC: low_level exception raised!");
ppc_state.pc = ppc_next_instruction_address;
exec_flags = 0;
return;
}
uint8_t* pc_real = mmu_translate_imem(ppc_state.pc);
uint32_t opcode = ppc_read_instruction(pc_real);
ppc_main_opcode(opcode);
exec_flags = ppc_main_opcode(opcode);
g_icycles++;
process_events();
@ -772,7 +773,6 @@ void ppc_cpu_init(MemCtrlBase* mem_ctrl, uint32_t cpu_version, bool do_include_6
tbr_freq_ghz = (tb_freq << 32) / NS_PER_SEC;
tbr_period_ns = ((uint64_t)NS_PER_SEC << 32) / tb_freq;
exec_flags = 0;
exec_timer = false;
timebase_counter = 0;

View File

@ -165,7 +165,7 @@ static void ppc_update_fex() {
// Floating Point Arithmetic
template <field_rc rec>
void dppc_interpreter::ppc_fadd(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fadd(uint32_t opcode) {
ppc_grab_regsfpdab(opcode);
max_double_check(val_reg_a, val_reg_b);
@ -193,13 +193,15 @@ void dppc_interpreter::ppc_fadd(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fadd<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fadd<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fadd<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fadd<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fsub(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fsub(uint32_t opcode) {
ppc_grab_regsfpdab(opcode);
double ppc_dblresult64_d = val_reg_a - val_reg_b;
@ -223,13 +225,15 @@ void dppc_interpreter::ppc_fsub(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fsub<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fsub<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fsub<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fsub<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fdiv(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fdiv(uint32_t opcode) {
ppc_grab_regsfpdab(opcode);
double ppc_dblresult64_d;
@ -237,7 +241,7 @@ void dppc_interpreter::ppc_fdiv(uint32_t opcode) {
if (is_601 && FPR_INT(reg_b) == 0x8000000000000000 && val_reg_a > 0) {
ppc_dblresult64_d = val_reg_b;
fpresult_update(ppc_dblresult64_d);
return;
return 0;
}
ppc_dblresult64_d = val_reg_a / val_reg_b;
@ -270,13 +274,15 @@ void dppc_interpreter::ppc_fdiv(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fdiv<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fdiv<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fdiv<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fdiv<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fmul(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fmul(uint32_t opcode) {
ppc_grab_regsfpdac(opcode);
double ppc_dblresult64_d = val_reg_a * val_reg_c;
@ -304,13 +310,15 @@ void dppc_interpreter::ppc_fmul(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fmul<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fmul<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fmul<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fmul<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fmadd(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fmadd(uint32_t opcode) {
ppc_grab_regsfpdabc(opcode);
double ppc_dblresult64_d = std::fma(val_reg_a, val_reg_c, val_reg_b);
@ -343,13 +351,15 @@ void dppc_interpreter::ppc_fmadd(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fmadd<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fmadd<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fmadd<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fmadd<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fmsub(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fmsub(uint32_t opcode) {
ppc_grab_regsfpdabc(opcode);
double ppc_dblresult64_d = std::fma(val_reg_a, val_reg_c, -val_reg_b);
@ -385,13 +395,15 @@ void dppc_interpreter::ppc_fmsub(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fmsub<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fmsub<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fmsub<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fmsub<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fnmadd(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fnmadd(uint32_t opcode) {
ppc_grab_regsfpdabc(opcode);
double ppc_dblresult64_d = -std::fma(val_reg_a, val_reg_c, val_reg_b);
@ -428,13 +440,15 @@ void dppc_interpreter::ppc_fnmadd(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fnmadd<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fnmadd<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fnmadd<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fnmadd<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fnmsub(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fnmsub(uint32_t opcode) {
ppc_grab_regsfpdabc(opcode);
double ppc_dblresult64_d = -std::fma(val_reg_a, val_reg_c, -val_reg_b);
@ -466,13 +480,15 @@ void dppc_interpreter::ppc_fnmsub(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fnmsub<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fnmsub<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fnmsub<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fnmsub<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fadds(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fadds(uint32_t opcode) {
ppc_grab_regsfpdab(opcode);
max_double_check(val_reg_a, val_reg_b);
@ -498,13 +514,15 @@ void dppc_interpreter::ppc_fadds(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fadds<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fadds<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fadds<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fadds<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fsubs(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fsubs(uint32_t opcode) {
ppc_grab_regsfpdab(opcode);
double ppc_dblresult64_d = (float)(val_reg_a - val_reg_b);
@ -529,13 +547,15 @@ void dppc_interpreter::ppc_fsubs(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fsubs<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fsubs<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fsubs<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fsubs<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fdivs(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fdivs(uint32_t opcode) {
ppc_grab_regsfpdab(opcode);
double ppc_dblresult64_d = (float)(val_reg_a / val_reg_b);
@ -570,13 +590,15 @@ void dppc_interpreter::ppc_fdivs(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fdivs<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fdivs<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fdivs<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fdivs<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fmuls(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fmuls(uint32_t opcode) {
ppc_grab_regsfpdac(opcode);
double ppc_dblresult64_d = (float)(val_reg_a * val_reg_c);
@ -604,13 +626,15 @@ void dppc_interpreter::ppc_fmuls(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fmuls<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fmuls<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fmuls<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fmuls<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fmadds(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fmadds(uint32_t opcode) {
ppc_grab_regsfpdabc(opcode);
double ppc_dblresult64_d = (float)std::fma(val_reg_a, val_reg_c, val_reg_b);
@ -639,13 +663,15 @@ void dppc_interpreter::ppc_fmadds(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fmadds<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fmadds<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fmadds<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fmadds<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fmsubs(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fmsubs(uint32_t opcode) {
ppc_grab_regsfpdabc(opcode);
double ppc_dblresult64_d = (float)std::fma(val_reg_a, val_reg_c, -val_reg_b);
@ -673,13 +699,15 @@ void dppc_interpreter::ppc_fmsubs(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fmsubs<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fmsubs<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fmsubs<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fmsubs<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fnmadds(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fnmadds(uint32_t opcode) {
ppc_grab_regsfpdabc(opcode);
double ppc_dblresult64_d = -(float)std::fma(val_reg_a, val_reg_c, val_reg_b);
@ -710,13 +738,15 @@ void dppc_interpreter::ppc_fnmadds(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fnmadds<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fnmadds<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fnmadds<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fnmadds<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fnmsubs(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fnmsubs(uint32_t opcode) {
ppc_grab_regsfpdabc(opcode);
snan_double_check(reg_a, reg_c);
@ -751,13 +781,15 @@ void dppc_interpreter::ppc_fnmsubs(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fnmsubs<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fnmsubs<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fnmsubs<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fnmsubs<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fabs(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fabs(uint32_t opcode) {
ppc_grab_regsfpdb(opcode);
uint64_t ppc_result64_d = FPR_INT(reg_b) & ~0x8000000000000000U;
@ -768,13 +800,15 @@ void dppc_interpreter::ppc_fabs(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fabs<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fabs<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fabs<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fabs<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fnabs(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fnabs(uint32_t opcode) {
ppc_grab_regsfpdb(opcode);
uint64_t ppc_result64_d = FPR_INT(reg_b) | 0x8000000000000000U;
@ -785,13 +819,15 @@ void dppc_interpreter::ppc_fnabs(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fnabs<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fnabs<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fnabs<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fnabs<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fneg(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fneg(uint32_t opcode) {
ppc_grab_regsfpdb(opcode);
uint64_t ppc_result64_d = FPR_INT(reg_b) ^ 0x8000000000000000U;
@ -802,13 +838,14 @@ void dppc_interpreter::ppc_fneg(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fneg<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fneg<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fneg<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fneg<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fsel(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fsel(uint32_t opcode) {
ppc_grab_regsfpdabc(opcode);
double ppc_dblresult64_d = (std::isnan(val_reg_a) || (val_reg_a < 0.0)) ? val_reg_b : val_reg_c;
@ -817,13 +854,14 @@ void dppc_interpreter::ppc_fsel(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fsel<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fsel<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fsel<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fsel<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fsqrt(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fsqrt(uint32_t opcode) {
ppc_grab_regsfpdb(opcode);
double testd2 = (double)(GET_FPR(reg_b));
@ -838,13 +876,14 @@ void dppc_interpreter::ppc_fsqrt(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fsqrt<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fsqrt<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fsqrt<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fsqrt<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fsqrts(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fsqrts(uint32_t opcode) {
ppc_grab_regsfpdb(opcode);
double testd2 = (double)(GET_FPR(reg_b));
@ -859,13 +898,14 @@ void dppc_interpreter::ppc_fsqrts(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fsqrts<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fsqrts<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fsqrts<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fsqrts<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_frsqrte(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_frsqrte(uint32_t opcode) {
ppc_grab_regsfpdb(opcode);
double testd2 = (double)(GET_FPR(reg_b));
@ -880,13 +920,14 @@ void dppc_interpreter::ppc_frsqrte(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_frsqrte<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_frsqrte<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_frsqrte<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_frsqrte<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_frsp(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_frsp(uint32_t opcode) {
ppc_grab_regsfpdb(opcode);
double ppc_dblresult64_d = (float)(GET_FPR(reg_b));
@ -900,13 +941,14 @@ void dppc_interpreter::ppc_frsp(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_frsp<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_frsp<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_frsp<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_frsp<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fres(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fres(uint32_t opcode) {
ppc_grab_regsfpdb(opcode);
double start_num = GET_FPR(reg_b);
@ -932,10 +974,11 @@ void dppc_interpreter::ppc_fres(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fres<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fres<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fres<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fres<RC1>(uint32_t opcode);
static void round_to_int(uint32_t opcode, const uint8_t mode, field_rc rec) {
ppc_grab_regsfpdb(opcode);
@ -995,32 +1038,35 @@ static void round_to_int(uint32_t opcode, const uint8_t mode, field_rc rec) {
}
template <field_rc rec>
void dppc_interpreter::ppc_fctiw(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fctiw(uint32_t opcode) {
round_to_int(opcode, ppc_state.fpscr & 0x3, rec);
return 0;
}
template void dppc_interpreter::ppc_fctiw<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fctiw<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fctiw<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fctiw<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_fctiwz(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fctiwz(uint32_t opcode) {
round_to_int(opcode, 1, rec);
return 0;
}
template void dppc_interpreter::ppc_fctiwz<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fctiwz<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fctiwz<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fctiwz<RC1>(uint32_t opcode);
// Floating Point Store and Load
void dppc_interpreter::ppc_lfs(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_lfs(uint32_t opcode) {
ppc_grab_regsfpdia(opcode);
uint32_t ea = int32_t(int16_t(opcode));
ea += (reg_a) ? val_reg_a : 0;
uint32_t result = mmu_read_vmem<uint32_t>(opcode, ea);
ppc_store_fpresult_flt(reg_d, *(float*)(&result));
return 0;
}
void dppc_interpreter::ppc_lfsu(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_lfsu(uint32_t opcode) {
ppc_grab_regsfpdia(opcode);
if (reg_a != 0) {
@ -1031,18 +1077,20 @@ void dppc_interpreter::ppc_lfsu(uint32_t opcode) {
ppc_store_iresult_reg(reg_a, ea);
}
else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP, 0);
}
return 0;
}
void dppc_interpreter::ppc_lfsx(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_lfsx(uint32_t opcode) {
ppc_grab_regsfpdiab(opcode);
uint32_t ea = val_reg_b + (reg_a ? val_reg_a : 0);
uint32_t result = mmu_read_vmem<uint32_t>(opcode, ea);
ppc_store_fpresult_flt(reg_d, *(float*)(&result));
return 0;
}
void dppc_interpreter::ppc_lfsux(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_lfsux(uint32_t opcode) {
ppc_grab_regsfpdiab(opcode);
if (reg_a != 0) {
@ -1050,22 +1098,24 @@ void dppc_interpreter::ppc_lfsux(uint32_t opcode) {
uint32_t result = mmu_read_vmem<uint32_t>(opcode, ea);
ppc_store_fpresult_flt(reg_d, *(float*)(&result));
ppc_store_iresult_reg(reg_a, ea);
return 0;
}
else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
return;
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP, 0);
return 0;
}
}
void dppc_interpreter::ppc_lfd(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_lfd(uint32_t opcode) {
ppc_grab_regsfpdia(opcode);
uint32_t ea = int32_t(int16_t(opcode));
ea += (reg_a) ? val_reg_a : 0;
uint64_t ppc_result64_d = mmu_read_vmem<uint64_t>(opcode, ea);
ppc_store_fpresult_int(reg_d, ppc_result64_d);
return 0;
}
void dppc_interpreter::ppc_lfdu(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_lfdu(uint32_t opcode) {
ppc_grab_regsfpdia(opcode);
if (reg_a != 0) {
@ -1076,18 +1126,20 @@ void dppc_interpreter::ppc_lfdu(uint32_t opcode) {
ppc_store_iresult_reg(reg_a, ea);
}
else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP, 0);
}
return 0;
}
void dppc_interpreter::ppc_lfdx(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_lfdx(uint32_t opcode) {
ppc_grab_regsfpdiab(opcode);
uint32_t ea = val_reg_b + (reg_a ? val_reg_a : 0);
uint64_t ppc_result64_d = mmu_read_vmem<uint64_t>(opcode, ea);
ppc_store_fpresult_int(reg_d, ppc_result64_d);
return 0;
}
void dppc_interpreter::ppc_lfdux(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_lfdux(uint32_t opcode) {
ppc_grab_regsfpdiab(opcode);
if (reg_a != 0) {
@ -1097,19 +1149,21 @@ void dppc_interpreter::ppc_lfdux(uint32_t opcode) {
ppc_store_iresult_reg(reg_a, ea);
}
else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP, 0);
}
return 0;
}
void dppc_interpreter::ppc_stfs(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_stfs(uint32_t opcode) {
ppc_grab_regsfpsia(opcode);
uint32_t ea = int32_t(int16_t(opcode));
ea += (reg_a) ? val_reg_a : 0;
float result = float(GET_FPR(reg_s));
mmu_write_vmem<uint32_t>(opcode, ea, *(uint32_t*)(&result));
return 0;
}
void dppc_interpreter::ppc_stfsu(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_stfsu(uint32_t opcode) {
ppc_grab_regsfpsia(opcode);
if (reg_a != 0) {
@ -1120,18 +1174,20 @@ void dppc_interpreter::ppc_stfsu(uint32_t opcode) {
ppc_store_iresult_reg(reg_a, ea);
}
else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP, 0);
}
return 0;
}
void dppc_interpreter::ppc_stfsx(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_stfsx(uint32_t opcode) {
ppc_grab_regsfpsiab(opcode);
uint32_t ea = val_reg_b + (reg_a ? val_reg_a : 0);
float result = float(GET_FPR(reg_s));
mmu_write_vmem<uint32_t>(opcode, ea, *(uint32_t*)(&result));
return 0;
}
void dppc_interpreter::ppc_stfsux(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_stfsux(uint32_t opcode) {
ppc_grab_regsfpsiab(opcode);
if (reg_a != 0) {
@ -1141,18 +1197,20 @@ void dppc_interpreter::ppc_stfsux(uint32_t opcode) {
ppc_store_iresult_reg(reg_a, ea);
}
else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP, 0);
}
return 0;
}
void dppc_interpreter::ppc_stfd(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_stfd(uint32_t opcode) {
ppc_grab_regsfpsia(opcode);
uint32_t ea = int32_t(int16_t(opcode));
ea += reg_a ? val_reg_a : 0;
mmu_write_vmem<uint64_t>(opcode, ea, FPR_INT(reg_s));
return 0;
}
void dppc_interpreter::ppc_stfdu(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_stfdu(uint32_t opcode) {
ppc_grab_regsfpsia(opcode);
if (reg_a != 0) {
@ -1162,17 +1220,19 @@ void dppc_interpreter::ppc_stfdu(uint32_t opcode) {
ppc_store_iresult_reg(reg_a, ea);
}
else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP, 0);
}
return 0;
}
void dppc_interpreter::ppc_stfdx(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_stfdx(uint32_t opcode) {
ppc_grab_regsfpsiab(opcode);
uint32_t ea = val_reg_b + (reg_a ? val_reg_a : 0);
mmu_write_vmem<uint64_t>(opcode, ea, FPR_INT(reg_s));
return 0;
}
void dppc_interpreter::ppc_stfdux(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_stfdux(uint32_t opcode) {
ppc_grab_regsfpsiab(opcode);
if (reg_a != 0) {
@ -1181,47 +1241,51 @@ void dppc_interpreter::ppc_stfdux(uint32_t opcode) {
ppc_store_iresult_reg(reg_a, ea);
}
else {
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP);
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::ILLEGAL_OP, 0);
}
return 0;
}
void dppc_interpreter::ppc_stfiwx(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_stfiwx(uint32_t opcode) {
ppc_grab_regsfpsiab(opcode);
uint32_t ea = val_reg_b + (reg_a ? val_reg_a : 0);
mmu_write_vmem<uint32_t>(opcode, ea, uint32_t(FPR_INT(reg_s)));
return 0;
}
// Floating Point Register Transfer
template <field_rc rec>
void dppc_interpreter::ppc_fmr(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fmr(uint32_t opcode) {
ppc_grab_regsfpdb(opcode);
ppc_store_fpresult_flt(reg_d, GET_FPR(reg_b));
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_fmr<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_fmr<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fmr<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_fmr<RC1>(uint32_t opcode);
template <field_601 for601, field_rc rec>
void dppc_interpreter::ppc_mffs(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_mffs(uint32_t opcode) {
int reg_d = (opcode >> 21) & 31;
ppc_store_fpresult_int(reg_d, uint64_t(ppc_state.fpscr) | (for601 ? 0xFFFFFFFF00000000ULL : 0xFFF8000000000000ULL));
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_mffs<NOT601, RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_mffs<NOT601, RC1>(uint32_t opcode);
template void dppc_interpreter::ppc_mffs<IS601, RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_mffs<IS601, RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_mffs<NOT601, RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_mffs<NOT601, RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_mffs<IS601, RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_mffs<IS601, RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_mtfsf(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_mtfsf(uint32_t opcode) {
int reg_b = (opcode >> 11) & 0x1F;
uint8_t fm = (opcode >> 17) & 0xFF;
@ -1248,13 +1312,14 @@ void dppc_interpreter::ppc_mtfsf(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_mtfsf<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_mtfsf<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_mtfsf<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_mtfsf<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_mtfsfi(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_mtfsfi(uint32_t opcode) {
int crf_d = (opcode >> 21) & 0x1C;
uint32_t imm = (opcode << 16) & 0xF0000000UL;
@ -1270,13 +1335,14 @@ void dppc_interpreter::ppc_mtfsfi(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_mtfsfi<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_mtfsfi<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_mtfsfi<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_mtfsfi<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_mtfsb0(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_mtfsb0(uint32_t opcode) {
int crf_d = (opcode >> 21) & 0x1F;
if (!crf_d || (crf_d > 2)) { // FEX and VX can't be explicitly cleared
ppc_state.fpscr &= ~(0x80000000UL >> crf_d);
@ -1284,13 +1350,14 @@ void dppc_interpreter::ppc_mtfsb0(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_mtfsb0<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_mtfsb0<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_mtfsb0<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_mtfsb0<RC1>(uint32_t opcode);
template <field_rc rec>
void dppc_interpreter::ppc_mtfsb1(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_mtfsb1(uint32_t opcode) {
int crf_d = (opcode >> 21) & 0x1F;
if (!crf_d || (crf_d > 2)) { // FEX and VX can't be explicitly set
ppc_state.fpscr |= (0x80000000UL >> crf_d);
@ -1298,12 +1365,13 @@ void dppc_interpreter::ppc_mtfsb1(uint32_t opcode) {
if (rec)
ppc_update_cr1();
return 0;
}
template void dppc_interpreter::ppc_mtfsb1<RC0>(uint32_t opcode);
template void dppc_interpreter::ppc_mtfsb1<RC1>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_mtfsb1<RC0>(uint32_t opcode);
template uint32_t dppc_interpreter::ppc_mtfsb1<RC1>(uint32_t opcode);
void dppc_interpreter::ppc_mcrfs(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_mcrfs(uint32_t opcode) {
int crf_d = (opcode >> 21) & 0x1C;
int crf_s = (opcode >> 16) & 0x1C;
ppc_state.cr = (
@ -1316,13 +1384,13 @@ void dppc_interpreter::ppc_mcrfs(uint32_t opcode) {
FPSCR::UX | FPSCR::ZX | FPSCR::XX | FPSCR::VXSNAN |
FPSCR::VXISI | FPSCR::VXIDI | FPSCR::VXZDZ | FPSCR::VXIMZ |
FPSCR::VXVC |
FPSCR::VXSOFT | FPSCR::VXSQRT | FPSCR::VXCVI
));
FPSCR::VXSOFT | FPSCR::VXSQRT | FPSCR::VXCVI));
return 0;
}
// Floating Point Comparisons
void dppc_interpreter::ppc_fcmpo(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fcmpo(uint32_t opcode) {
ppc_grab_regsfpsab(opcode);
uint32_t cmp_c = 0;
@ -1349,10 +1417,11 @@ void dppc_interpreter::ppc_fcmpo(uint32_t opcode) {
ppc_state.fpscr &= ~VE; //kludge to pass tests
ppc_state.fpscr = (ppc_state.fpscr & ~FPSCR::FPCC_MASK) | (cmp_c >> 16); // update FPCC
ppc_state.cr = ((ppc_state.cr & ~(0xF0000000 >> crf_d)) | (cmp_c >> crf_d));
ppc_state.cr = ((ppc_state.cr & ~(0xF0000000 >> crf_d)) | (cmp_c >> crf_d));
return 0;
}
void dppc_interpreter::ppc_fcmpu(uint32_t opcode) {
uint32_t dppc_interpreter::ppc_fcmpu(uint32_t opcode) {
ppc_grab_regsfpsab(opcode);
uint32_t cmp_c = 0;
@ -1376,4 +1445,5 @@ void dppc_interpreter::ppc_fcmpu(uint32_t opcode) {
ppc_state.fpscr &= ~VE; //kludge to pass tests
ppc_state.fpscr = (ppc_state.fpscr & ~FPSCR::FPCC_MASK) | (cmp_c >> 16); // update FPCC
ppc_state.cr = ((ppc_state.cr & ~(0xF0000000UL >> crf_d)) | (cmp_c >> crf_d));
return 0;
}

View File

@ -36,7 +36,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
//#define TLB_PROFILING // uncomment this to enable SoftTLB profiling
/* pointer to exception handler to be called when a MMU exception is occurred. */
void (*mmu_exception_handler)(Except_Type exception_type, uint32_t srr1_bits);
uint32_t (*mmu_exception_handler)(Except_Type exception_type, uint32_t srr1_bits, uint32_t exec_flags);
/* pointers to BAT update functions. */
std::function<void(uint32_t bat_reg)> ibat_update;
@ -250,7 +250,7 @@ static PATResult page_address_translation(uint32_t la, bool is_instr_fetch,
/* instruction fetch from a no-execute segment will cause ISI exception */
if ((sr_val & 0x10000000) && is_instr_fetch) {
mmu_exception_handler(Except_Type::EXC_ISI, 0x10000000);
mmu_exception_handler(Except_Type::EXC_ISI, 0x10000000, 0);
}
page_index = (la >> 12) & 0xFFFF;
@ -260,11 +260,11 @@ static PATResult page_address_translation(uint32_t la, bool is_instr_fetch,
if (!search_pteg(calc_pteg_addr(pteg_hash1), &pte_addr, vsid, page_index, 0)) {
if (!search_pteg(calc_pteg_addr(~pteg_hash1), &pte_addr, vsid, page_index, 1)) {
if (is_instr_fetch) {
mmu_exception_handler(Except_Type::EXC_ISI, 0x40000000);
mmu_exception_handler(Except_Type::EXC_ISI, 0x40000000, 0);
} else {
ppc_state.spr[SPR::DSISR] = 0x40000000 | (is_write << 25);
ppc_state.spr[SPR::DAR] = la;
mmu_exception_handler(Except_Type::EXC_DSI, 0);
mmu_exception_handler(Except_Type::EXC_DSI, 0, 0);
}
}
}
@ -282,11 +282,11 @@ static PATResult page_address_translation(uint32_t la, bool is_instr_fetch,
// write access with PP = %11
if ((key && (!pp || (pp == 1 && is_write))) || (pp == 3 && is_write)) {
if (is_instr_fetch) {
mmu_exception_handler(Except_Type::EXC_ISI, 0x08000000);
mmu_exception_handler(Except_Type::EXC_ISI, 0x08000000, 0);
} else {
ppc_state.spr[SPR::DSISR] = 0x08000000 | (is_write << 25);
ppc_state.spr[SPR::DAR] = la;
mmu_exception_handler(Except_Type::EXC_DSI, 0);
mmu_exception_handler(Except_Type::EXC_DSI, 0, 0);
}
}
@ -527,7 +527,7 @@ static TLBEntry* itlb2_refill(uint32_t guest_va)
// check block protection
// only PP = 0 (no access) causes ISI exception
if (!bat_res.prot) {
mmu_exception_handler(Except_Type::EXC_ISI, 0x08000000);
mmu_exception_handler(Except_Type::EXC_ISI, 0x08000000, 0);
}
phys_addr = bat_res.phys;
flags |= TLBFlags::TLBE_FROM_BAT; // tell the world we come from
@ -588,7 +588,7 @@ static TLBEntry* dtlb2_refill(uint32_t guest_va, int is_write, bool is_dbg = fal
LOG_F(9, "Attempt to write to read-only region, LA=0x%08X, PC=0x%08X!", guest_va, ppc_state.pc);
ppc_state.spr[SPR::DSISR] = 0x08000000 | (is_write << 25);
ppc_state.spr[SPR::DAR] = guest_va;
mmu_exception_handler(Except_Type::EXC_DSI, 0);
mmu_exception_handler(Except_Type::EXC_DSI, 0, 0);
}
phys_addr = bat_res.phys;
flags = TLBFlags::PTE_SET_C; // prevent PTE.C updates for BAT
@ -1099,7 +1099,7 @@ inline void mmu_write_vmem(uint32_t opcode, uint32_t guest_va, T value)
if (!(tlb1_entry->flags & TLBFlags::PAGE_WRITABLE)) {
ppc_state.spr[SPR::DSISR] = 0x08000000 | (1 << 25);
ppc_state.spr[SPR::DAR] = guest_va;
mmu_exception_handler(Except_Type::EXC_DSI, 0);
mmu_exception_handler(Except_Type::EXC_DSI, 0, 0);
}
if (!(tlb1_entry->flags & TLBFlags::PTE_SET_C)) {
// perform full page address translation to update PTE.C bit
@ -1136,7 +1136,7 @@ inline void mmu_write_vmem(uint32_t opcode, uint32_t guest_va, T value)
if (!(tlb2_entry->flags & TLBFlags::PAGE_WRITABLE)) {
ppc_state.spr[SPR::DSISR] = 0x08000000 | (1 << 25);
ppc_state.spr[SPR::DAR] = guest_va;
mmu_exception_handler(Except_Type::EXC_DSI, 0);
mmu_exception_handler(Except_Type::EXC_DSI, 0, 0);
}
if (!(tlb2_entry->flags & TLBFlags::PTE_SET_C)) {

File diff suppressed because it is too large Load Diff

View File

@ -229,7 +229,7 @@ uint32_t PCIHost::pci_io_read_broadcast(uint32_t offset, int size)
SIZE_ARG(size)
);
// machine check exception (DEFAULT CATCH!, code=FFF00200)
ppc_exception_handler(Except_Type::EXC_MACHINE_CHECK, 0);
ppc_exception_handler(Except_Type::EXC_MACHINE_CHECK, 0, 0);
return 0;
}