mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-20 01:29:43 +00:00
initial attempt to remove global variable exec_flags
This commit is contained in:
parent
e63f928a3c
commit
c25ad96e3a
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
381
cpu/ppc/ppcemu.h
381
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)(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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user