mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-09 06:30:51 +00:00
Attempted templating for interpreter
This commit is contained in:
parent
1d5502dc3c
commit
c281b27220
@ -44,24 +44,30 @@ static inline uint32_t power_rot_mask(unsigned rot_mb, unsigned rot_me) {
|
||||
return ((rot_mb <= rot_me) ? m2 & m1 : m1 | m2);
|
||||
}
|
||||
|
||||
template <bool rec, bool ov>
|
||||
void dppc_interpreter::power_abs() {
|
||||
uint32_t ppc_result_d;
|
||||
ppc_grab_regsda(ppc_cur_instruction);
|
||||
if (ppc_result_a == 0x80000000) {
|
||||
ppc_result_d = ppc_result_a;
|
||||
if (oe_flag)
|
||||
if (ov)
|
||||
ppc_state.spr[SPR::XER] |= 0xC0000000;
|
||||
|
||||
} else {
|
||||
ppc_result_d = ppc_result_a & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_d);
|
||||
|
||||
ppc_store_iresult_reg(reg_d, ppc_result_d);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_abs<RC0, OV0>();
|
||||
template void dppc_interpreter::power_abs<RC0, OV1>();
|
||||
template void dppc_interpreter::power_abs<RC1, OV0>();
|
||||
template void dppc_interpreter::power_abs<RC1, OV1>();
|
||||
|
||||
void dppc_interpreter::power_clcs() {
|
||||
uint32_t ppc_result_d;
|
||||
ppc_grab_regsda(ppc_cur_instruction);
|
||||
@ -79,6 +85,7 @@ void dppc_interpreter::power_clcs() {
|
||||
ppc_store_iresult_reg(reg_d, ppc_result_d);
|
||||
}
|
||||
|
||||
template <bool rec, bool ov>
|
||||
void dppc_interpreter::power_div() {
|
||||
uint32_t ppc_result_d;
|
||||
ppc_grab_regsdab(ppc_cur_instruction);
|
||||
@ -94,40 +101,57 @@ void dppc_interpreter::power_div() {
|
||||
ppc_state.spr[SPR::MQ] = dividend % divisor;
|
||||
}
|
||||
|
||||
if (oe_flag)
|
||||
if (ov)
|
||||
power_setsoov(ppc_result_b, ppc_result_a, ppc_result_d);
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_d);
|
||||
|
||||
ppc_store_iresult_reg(reg_d, ppc_result_d);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_div<RC0, OV0>();
|
||||
template void dppc_interpreter::power_div<RC0, OV1>();
|
||||
template void dppc_interpreter::power_div<RC1, OV0>();
|
||||
template void dppc_interpreter::power_div<RC1, OV1>();
|
||||
|
||||
template <bool rec, bool ov>
|
||||
void dppc_interpreter::power_divs() {
|
||||
ppc_grab_regsdab(ppc_cur_instruction);
|
||||
uint32_t ppc_result_d = ppc_result_a / ppc_result_b;
|
||||
ppc_state.spr[SPR::MQ] = (ppc_result_a % ppc_result_b);
|
||||
|
||||
if (oe_flag)
|
||||
if (ov)
|
||||
power_setsoov(ppc_result_b, ppc_result_a, ppc_result_d);
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_d);
|
||||
|
||||
ppc_store_iresult_reg(reg_d, ppc_result_d);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_divs<RC0, OV0>();
|
||||
template void dppc_interpreter::power_divs<RC0, OV1>();
|
||||
template void dppc_interpreter::power_divs<RC1, OV0>();
|
||||
template void dppc_interpreter::power_divs<RC1, OV1>();
|
||||
|
||||
template <bool rec, bool ov>
|
||||
void dppc_interpreter::power_doz() {
|
||||
ppc_grab_regsdab(ppc_cur_instruction);
|
||||
uint32_t ppc_result_d = (int32_t(ppc_result_a) >= int32_t(ppc_result_b))\
|
||||
? 0 : ppc_result_b - ppc_result_a;
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_d);
|
||||
if (oe_flag)
|
||||
if (ov)
|
||||
power_setsoov(ppc_result_a, ppc_result_b, ppc_result_d);
|
||||
|
||||
ppc_store_iresult_reg(reg_d, ppc_result_d);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_doz<RC0, OV0>();
|
||||
template void dppc_interpreter::power_doz<RC0, OV1>();
|
||||
template void dppc_interpreter::power_doz<RC1, OV0>();
|
||||
template void dppc_interpreter::power_doz<RC1, OV1>();
|
||||
|
||||
void dppc_interpreter::power_dozi() {
|
||||
uint32_t ppc_result_d;
|
||||
ppc_grab_regsdasimm(ppc_cur_instruction);
|
||||
@ -139,6 +163,7 @@ void dppc_interpreter::power_dozi() {
|
||||
ppc_store_iresult_reg(reg_d, ppc_result_d);
|
||||
}
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::power_lscbx() {
|
||||
ppc_grab_regsdab(ppc_cur_instruction);
|
||||
ppc_effective_address = ppc_result_b + (reg_a ? ppc_result_a : 0);
|
||||
@ -182,10 +207,14 @@ void dppc_interpreter::power_lscbx() {
|
||||
|
||||
ppc_state.spr[SPR::XER] = (ppc_state.spr[SPR::XER] & ~0x7F) | bytes_copied;
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_d);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_lscbx<RC0>();
|
||||
template void dppc_interpreter::power_lscbx<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::power_maskg() {
|
||||
ppc_grab_regssab(ppc_cur_instruction);
|
||||
uint32_t mask_start = ppc_result_d & 31;
|
||||
@ -204,22 +233,30 @@ void dppc_interpreter::power_maskg() {
|
||||
|
||||
ppc_result_a = insert_mask;
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_d);
|
||||
|
||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_maskg<RC0>();
|
||||
template void dppc_interpreter::power_maskg<true>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::power_maskir() {
|
||||
ppc_grab_regssab(ppc_cur_instruction);
|
||||
ppc_result_a = (ppc_result_a & ~ppc_result_b) | (ppc_result_d & ppc_result_b);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
|
||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_maskir<RC0>();
|
||||
template void dppc_interpreter::power_maskir<true>();
|
||||
|
||||
template <bool rec, bool ov>
|
||||
void dppc_interpreter::power_mul() {
|
||||
ppc_grab_regsdab(ppc_cur_instruction);
|
||||
uint64_t product;
|
||||
@ -228,22 +265,37 @@ void dppc_interpreter::power_mul() {
|
||||
uint32_t ppc_result_d = ((uint32_t)(product >> 32));
|
||||
ppc_state.spr[SPR::MQ] = ((uint32_t)(product));
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_d);
|
||||
if (ov)
|
||||
power_setsoov(ppc_result_a, ppc_result_b, ppc_result_d);
|
||||
|
||||
ppc_store_iresult_reg(reg_d, ppc_result_d);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_mul<RC0, OV0>();
|
||||
template void dppc_interpreter::power_mul<RC0, OV1>();
|
||||
template void dppc_interpreter::power_mul<RC1, OV0>();
|
||||
template void dppc_interpreter::power_mul<RC1, OV1>();
|
||||
|
||||
template <bool rec, bool ov>
|
||||
void dppc_interpreter::power_nabs() {
|
||||
ppc_grab_regsda(ppc_cur_instruction);
|
||||
uint32_t ppc_result_d = ppc_result_a & 0x80000000 ? ppc_result_a : -ppc_result_a;
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_d);
|
||||
if (ov)
|
||||
ppc_state.spr[SPR::XER] &= 0xBFFFFFFFUL;
|
||||
|
||||
ppc_store_iresult_reg(reg_d, ppc_result_d);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_nabs<RC0, OV0>();
|
||||
template void dppc_interpreter::power_nabs<RC0, OV1>();
|
||||
template void dppc_interpreter::power_nabs<RC1, OV0>();
|
||||
template void dppc_interpreter::power_nabs<RC1, OV1>();
|
||||
|
||||
void dppc_interpreter::power_rlmi() {
|
||||
ppc_grab_regssab(ppc_cur_instruction);
|
||||
unsigned rot_mb = (ppc_cur_instruction >> 6) & 31;
|
||||
@ -255,12 +307,13 @@ void dppc_interpreter::power_rlmi() {
|
||||
|
||||
ppc_result_a = ((r & mask) | (ppc_result_a & ~mask));
|
||||
|
||||
if (rc_flag)
|
||||
if ((ppc_cur_instruction & 0x01) == 1)
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
|
||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||
}
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::power_rrib() {
|
||||
ppc_grab_regssab(ppc_cur_instruction);
|
||||
|
||||
@ -270,12 +323,16 @@ void dppc_interpreter::power_rrib() {
|
||||
ppc_result_a &= ~((ppc_result_d & 0x80000000) >> ppc_result_b);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
|
||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_rrib<RC0>();
|
||||
template void dppc_interpreter::power_rrib<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::power_sle() {
|
||||
ppc_grab_regssab(ppc_cur_instruction);
|
||||
unsigned rot_sh = ppc_result_b & 31;
|
||||
@ -285,12 +342,16 @@ void dppc_interpreter::power_sle() {
|
||||
|
||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
|
||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_sle<RC0>();
|
||||
template void dppc_interpreter::power_sle<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::power_sleq() {
|
||||
ppc_grab_regssab(ppc_cur_instruction);
|
||||
unsigned rot_sh = ppc_result_b & 31;
|
||||
@ -300,12 +361,16 @@ void dppc_interpreter::power_sleq() {
|
||||
ppc_result_a = ((r & mask) | (ppc_state.spr[SPR::MQ] & ~mask));
|
||||
ppc_state.spr[SPR::MQ] = r;
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
|
||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_sleq<RC0>();
|
||||
template void dppc_interpreter::power_sleq<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::power_sliq() {
|
||||
ppc_grab_regssa(ppc_cur_instruction);
|
||||
unsigned rot_sh = (ppc_cur_instruction >> 11) & 31;
|
||||
@ -313,12 +378,16 @@ void dppc_interpreter::power_sliq() {
|
||||
ppc_result_a = ppc_result_d << rot_sh;
|
||||
ppc_state.spr[SPR::MQ] = ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh)));
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
|
||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_sliq<RC0>();
|
||||
template void dppc_interpreter::power_sliq<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::power_slliq() {
|
||||
ppc_grab_regssa(ppc_cur_instruction);
|
||||
unsigned rot_sh = (ppc_cur_instruction >> 11) & 31;
|
||||
@ -328,12 +397,16 @@ void dppc_interpreter::power_slliq() {
|
||||
ppc_result_a = ((r & mask) | (ppc_state.spr[SPR::MQ] & ~mask));
|
||||
ppc_state.spr[SPR::MQ] = r;
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
|
||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_slliq<RC0>();
|
||||
template void dppc_interpreter::power_slliq<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::power_sllq() {
|
||||
ppc_grab_regssab(ppc_cur_instruction);
|
||||
unsigned rot_sh = ppc_result_b & 31;
|
||||
@ -347,12 +420,16 @@ void dppc_interpreter::power_sllq() {
|
||||
ppc_result_a = ((r & mask) | (ppc_state.spr[SPR::MQ] & ~mask));
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
|
||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_sllq<RC0>();
|
||||
template void dppc_interpreter::power_sllq<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::power_slq() {
|
||||
ppc_grab_regssab(ppc_cur_instruction);
|
||||
unsigned rot_sh = ppc_result_b & 31;
|
||||
@ -363,12 +440,16 @@ void dppc_interpreter::power_slq() {
|
||||
ppc_result_a = 0;
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
|
||||
ppc_state.spr[SPR::MQ] = ((ppc_result_d << rot_sh) | (ppc_result_d >> (32 - rot_sh)));
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_slq<RC0>();
|
||||
template void dppc_interpreter::power_slq<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::power_sraiq() {
|
||||
ppc_grab_regssa(ppc_cur_instruction);
|
||||
unsigned rot_sh = (ppc_cur_instruction >> 11) & 0x1F;
|
||||
@ -382,12 +463,16 @@ void dppc_interpreter::power_sraiq() {
|
||||
ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
|
||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_sraiq<RC0>();
|
||||
template void dppc_interpreter::power_sraiq<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::power_sraq() {
|
||||
ppc_grab_regssab(ppc_cur_instruction);
|
||||
unsigned rot_sh = ppc_result_b & 0x1F;
|
||||
@ -403,12 +488,16 @@ void dppc_interpreter::power_sraq() {
|
||||
|
||||
ppc_state.spr[SPR::MQ] = (ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh));
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
|
||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_sraq<RC0>();
|
||||
template void dppc_interpreter::power_sraq<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::power_sre() {
|
||||
ppc_grab_regssab(ppc_cur_instruction);
|
||||
|
||||
@ -417,12 +506,16 @@ void dppc_interpreter::power_sre() {
|
||||
ppc_result_a = ppc_result_d >> rot_sh;
|
||||
ppc_state.spr[SPR::MQ] = (ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh));
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
|
||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_sre<RC0>();
|
||||
template void dppc_interpreter::power_sre<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::power_srea() {
|
||||
ppc_grab_regssab(ppc_cur_instruction);
|
||||
unsigned rot_sh = ppc_result_b & 0x1F;
|
||||
@ -435,12 +528,16 @@ void dppc_interpreter::power_srea() {
|
||||
ppc_state.spr[SPR::XER] &= 0xDFFFFFFFUL;
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
|
||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_srea<RC0>();
|
||||
template void dppc_interpreter::power_srea<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::power_sreq() {
|
||||
ppc_grab_regssab(ppc_cur_instruction);
|
||||
unsigned rot_sh = ppc_result_b & 31;
|
||||
@ -449,24 +546,32 @@ void dppc_interpreter::power_sreq() {
|
||||
ppc_result_a = ((rot_sh & mask) | (ppc_state.spr[SPR::MQ] & ~mask));
|
||||
ppc_state.spr[SPR::MQ] = rot_sh;
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
|
||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_sreq<RC0>();
|
||||
template void dppc_interpreter::power_sreq<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::power_sriq() {
|
||||
ppc_grab_regssa(ppc_cur_instruction);
|
||||
unsigned rot_sh = (ppc_cur_instruction >> 11) & 31;
|
||||
ppc_result_a = ppc_result_d >> rot_sh;
|
||||
ppc_state.spr[SPR::MQ] = (ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh));
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
|
||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_sriq<RC0>();
|
||||
template void dppc_interpreter::power_sriq<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::power_srliq() {
|
||||
ppc_grab_regssa(ppc_cur_instruction);
|
||||
unsigned rot_sh = (ppc_cur_instruction >> 11) & 31;
|
||||
@ -477,12 +582,16 @@ void dppc_interpreter::power_srliq() {
|
||||
ppc_result_a = ((r & mask) | (ppc_state.spr[SPR::MQ] & ~mask));
|
||||
ppc_state.spr[SPR::MQ] = r;
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
|
||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_srliq<RC0>();
|
||||
template void dppc_interpreter::power_srliq<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::power_srlq() {
|
||||
ppc_grab_regssab(ppc_cur_instruction);
|
||||
unsigned rot_sh = ppc_result_b & 31;
|
||||
@ -496,12 +605,16 @@ void dppc_interpreter::power_srlq() {
|
||||
ppc_result_a = ((r & mask) | (ppc_state.spr[SPR::MQ] & ~mask));
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
|
||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_srlq<RC0>();
|
||||
template void dppc_interpreter::power_srlq<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::power_srq() {
|
||||
ppc_grab_regssab(ppc_cur_instruction);
|
||||
unsigned rot_sh = ppc_result_b & 31;
|
||||
@ -514,8 +627,11 @@ void dppc_interpreter::power_srq() {
|
||||
|
||||
ppc_state.spr[SPR::MQ] = (ppc_result_d >> rot_sh) | (ppc_result_d << (32 - rot_sh));
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_a);
|
||||
|
||||
ppc_store_iresult_reg(reg_a, ppc_result_a);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::power_srq<RC0>();
|
||||
template void dppc_interpreter::power_srq<RC1>();
|
247
cpu/ppc/ppcemu.h
247
cpu/ppc/ppcemu.h
@ -331,9 +331,6 @@ extern bool is_601; // For PowerPC 601 Emulation
|
||||
extern bool is_altivec; // For Altivec Emulation
|
||||
extern bool is_64bit; // For PowerPC G5 Emulation
|
||||
|
||||
extern bool rc_flag; // Record flag
|
||||
extern bool oe_flag; // Overflow flag
|
||||
|
||||
// Important Addressing Integers
|
||||
extern uint32_t ppc_cur_instruction;
|
||||
extern uint32_t ppc_effective_address;
|
||||
@ -391,6 +388,35 @@ extern void add_ctx_sync_action(const std::function<void()> &);
|
||||
extern void do_ctx_sync(void);
|
||||
|
||||
// The functions used by the PowerPC processor
|
||||
|
||||
enum bool_fun {
|
||||
bool_and = 1,
|
||||
bool_andc = 2,
|
||||
bool_eqv = 3,
|
||||
bool_nand = 4,
|
||||
bool_nor = 5,
|
||||
bool_or = 6,
|
||||
bool_orc = 7,
|
||||
bool_xor = 8,
|
||||
};
|
||||
|
||||
enum field_setting {
|
||||
LK0 = 0,
|
||||
LK1 = 1,
|
||||
AA0 = 0,
|
||||
AA1 = 1,
|
||||
LSHFT = 0,
|
||||
RSHFT = 1,
|
||||
RC0 = 0,
|
||||
RC1 = 1,
|
||||
OV0 = 0,
|
||||
OV1 = 1,
|
||||
CARRY0 = 0,
|
||||
CARRY1 = 1,
|
||||
IS601 = 0,
|
||||
NOT601 = 1
|
||||
};
|
||||
|
||||
namespace dppc_interpreter {
|
||||
template <bool l, bool for601> extern void ppc_bcctr();
|
||||
template <bool l> extern void ppc_bclr();
|
||||
@ -404,72 +430,55 @@ extern void ppc_crorc();
|
||||
extern void ppc_crxor();
|
||||
extern void ppc_isync();
|
||||
|
||||
extern void ppc_add();
|
||||
extern void ppc_addc();
|
||||
extern void ppc_adde();
|
||||
extern void ppc_addme();
|
||||
extern void ppc_addze();
|
||||
extern void ppc_and();
|
||||
extern void ppc_andc();
|
||||
template <int bool_op, bool rec> extern void ppc_do_bool();
|
||||
|
||||
template <bool carry, bool rec, bool ov> extern void ppc_add();
|
||||
template <bool rec, bool ov> extern void ppc_adde();
|
||||
template <bool rec, bool ov> extern void ppc_addme();
|
||||
template <bool rec, bool ov> extern void ppc_addze();
|
||||
extern void ppc_cmp();
|
||||
extern void ppc_cmpl();
|
||||
extern void ppc_cntlzw();
|
||||
template <bool rec> extern void ppc_cntlzw();
|
||||
extern void ppc_dcbf();
|
||||
extern void ppc_dcbi();
|
||||
extern void ppc_dcbst();
|
||||
extern void ppc_dcbt();
|
||||
extern void ppc_dcbtst();
|
||||
extern void ppc_dcbz();
|
||||
extern void ppc_divw();
|
||||
extern void ppc_divwu();
|
||||
template <bool rec, bool ov> extern void ppc_divw();
|
||||
template <bool rec, bool ov> extern void ppc_divwu();
|
||||
extern void ppc_eciwx();
|
||||
extern void ppc_ecowx();
|
||||
extern void ppc_eieio();
|
||||
extern void ppc_eqv();
|
||||
extern void ppc_extsb();
|
||||
extern void ppc_extsh();
|
||||
template <class T, bool rec>extern void ppc_exts();
|
||||
extern void ppc_icbi();
|
||||
extern void ppc_mftb();
|
||||
extern void ppc_lhzux();
|
||||
extern void ppc_lhzx();
|
||||
extern void ppc_lhaux();
|
||||
extern void ppc_lhax();
|
||||
extern void ppc_lhbrx();
|
||||
extern void ppc_lwarx();
|
||||
extern void ppc_lbzux();
|
||||
extern void ppc_lbzx();
|
||||
extern void ppc_lwbrx();
|
||||
extern void ppc_lwzux();
|
||||
extern void ppc_lwzx();
|
||||
template <class T> extern void ppc_lzx();
|
||||
template <class T> extern void ppc_lzux();
|
||||
extern void ppc_mcrxr();
|
||||
extern void ppc_mfcr();
|
||||
extern void ppc_mulhwu();
|
||||
extern void ppc_mulhw();
|
||||
extern void ppc_mullw();
|
||||
extern void ppc_nand();
|
||||
extern void ppc_neg();
|
||||
extern void ppc_nor();
|
||||
extern void ppc_or();
|
||||
extern void ppc_orc();
|
||||
extern void ppc_slw();
|
||||
extern void ppc_srw();
|
||||
extern void ppc_sraw();
|
||||
extern void ppc_srawi();
|
||||
extern void ppc_stbx();
|
||||
extern void ppc_stbux();
|
||||
template <bool rec> extern void ppc_mulhwu();
|
||||
template <bool rec> extern void ppc_mulhw();
|
||||
template <bool rec, bool ov> extern void ppc_mullw();
|
||||
template <bool rec, bool ov> extern void ppc_neg();
|
||||
template <bool left, bool rec> extern void ppc_shift();
|
||||
template <bool rec> extern void ppc_sraw();
|
||||
template <bool rec> extern void ppc_srawi();
|
||||
template <class T> extern void ppc_stx();
|
||||
template <class T> extern void ppc_stux();
|
||||
extern void ppc_stfiwx();
|
||||
extern void ppc_sthx();
|
||||
extern void ppc_sthux();
|
||||
extern void ppc_sthbrx();
|
||||
extern void ppc_stwx();
|
||||
extern void ppc_stwcx();
|
||||
extern void ppc_stwux();
|
||||
extern void ppc_stwbrx();
|
||||
extern void ppc_subf();
|
||||
extern void ppc_subfc();
|
||||
extern void ppc_subfe();
|
||||
extern void ppc_subfme();
|
||||
extern void ppc_subfze();
|
||||
template <bool carry, bool rec, bool ov> extern void ppc_subf();
|
||||
template <bool rec, bool ov> extern void ppc_subfe();
|
||||
template <bool rec, bool ov> extern void ppc_subfme();
|
||||
template <bool rec, bool ov> extern void ppc_subfze();
|
||||
extern void ppc_sync();
|
||||
extern void ppc_tlbia();
|
||||
extern void ppc_tlbie();
|
||||
@ -477,7 +486,6 @@ extern void ppc_tlbli();
|
||||
extern void ppc_tlbld();
|
||||
extern void ppc_tlbsync();
|
||||
extern void ppc_tw();
|
||||
extern void ppc_xor();
|
||||
|
||||
extern void ppc_lswi();
|
||||
extern void ppc_lswx();
|
||||
@ -496,52 +504,39 @@ extern void ppc_mfspr();
|
||||
extern void ppc_mtmsr();
|
||||
extern void ppc_mtspr();
|
||||
|
||||
extern void ppc_mtfsb0();
|
||||
extern void ppc_mtfsb1();
|
||||
template <bool rec> extern void ppc_mtfsb0();
|
||||
template <bool rec> extern void ppc_mtfsb1();
|
||||
extern void ppc_mcrfs();
|
||||
extern void ppc_fmr();
|
||||
template <bool for601> extern void ppc_mffs();
|
||||
extern void ppc_mtfsf();
|
||||
extern void ppc_mtfsfi();
|
||||
template <bool rec> extern void ppc_fmr();
|
||||
template <bool for601, bool rec> extern void ppc_mffs();
|
||||
template <bool rec> extern void ppc_mtfsf();
|
||||
template <bool rec> extern void ppc_mtfsfi();
|
||||
|
||||
extern void ppc_addi();
|
||||
extern void ppc_addic();
|
||||
extern void ppc_addicdot();
|
||||
extern void ppc_addis();
|
||||
extern void ppc_andidot();
|
||||
extern void ppc_andisdot();
|
||||
template <bool shift> extern void ppc_addi();
|
||||
template <bool rec> extern void ppc_addic();
|
||||
template <bool shift> extern void ppc_andirc();
|
||||
template <bool l, bool a> extern void ppc_b();
|
||||
template <bool l, bool a> extern void ppc_bc();
|
||||
extern void ppc_cmpi();
|
||||
extern void ppc_cmpli();
|
||||
extern void ppc_lbz();
|
||||
extern void ppc_lbzu();
|
||||
template <class T> extern void ppc_lz();
|
||||
template <class T> extern void ppc_lzu();
|
||||
extern void ppc_lha();
|
||||
extern void ppc_lhau();
|
||||
extern void ppc_lhz();
|
||||
extern void ppc_lhzu();
|
||||
extern void ppc_lwz();
|
||||
extern void ppc_lwzu();
|
||||
extern void ppc_lmw();
|
||||
extern void ppc_mulli();
|
||||
extern void ppc_ori();
|
||||
extern void ppc_oris();
|
||||
template <bool shift> extern void ppc_ori();
|
||||
extern void ppc_rfi();
|
||||
extern void ppc_rlwimi();
|
||||
extern void ppc_rlwinm();
|
||||
extern void ppc_rlwnm();
|
||||
extern void ppc_sc();
|
||||
extern void ppc_stb();
|
||||
extern void ppc_stbu();
|
||||
extern void ppc_sth();
|
||||
extern void ppc_sthu();
|
||||
extern void ppc_stw();
|
||||
extern void ppc_stwu();
|
||||
template <class T> extern void ppc_st();
|
||||
template <class T> extern void ppc_stu();
|
||||
extern void ppc_stmw();
|
||||
extern void ppc_subfic();
|
||||
extern void ppc_twi();
|
||||
extern void ppc_xori();
|
||||
extern void ppc_xoris();
|
||||
template <bool shift> extern void ppc_xori();
|
||||
|
||||
extern void ppc_lfs();
|
||||
extern void ppc_lfsu();
|
||||
@ -560,66 +555,66 @@ extern void ppc_stfdu();
|
||||
extern void ppc_stfdx();
|
||||
extern void ppc_stfdux();
|
||||
|
||||
extern void ppc_fadd();
|
||||
extern void ppc_fsub();
|
||||
extern void ppc_fmul();
|
||||
extern void ppc_fdiv();
|
||||
extern void ppc_fadds();
|
||||
extern void ppc_fsubs();
|
||||
extern void ppc_fmuls();
|
||||
extern void ppc_fdivs();
|
||||
extern void ppc_fmadd();
|
||||
extern void ppc_fmsub();
|
||||
extern void ppc_fnmadd();
|
||||
extern void ppc_fnmsub();
|
||||
extern void ppc_fmadds();
|
||||
extern void ppc_fmsubs();
|
||||
extern void ppc_fnmadds();
|
||||
extern void ppc_fnmsubs();
|
||||
extern void ppc_fabs();
|
||||
extern void ppc_fnabs();
|
||||
extern void ppc_fneg();
|
||||
extern void ppc_fsel();
|
||||
extern void ppc_fres();
|
||||
extern void ppc_fsqrts();
|
||||
extern void ppc_fsqrt();
|
||||
extern void ppc_frsqrte();
|
||||
extern void ppc_frsp();
|
||||
extern void ppc_fctiw();
|
||||
extern void ppc_fctiwz();
|
||||
template <bool rec> extern void ppc_fadd();
|
||||
template <bool rec> extern void ppc_fsub();
|
||||
template <bool rec> extern void ppc_fmul();
|
||||
template <bool rec> extern void ppc_fdiv();
|
||||
template <bool rec> extern void ppc_fadds();
|
||||
template <bool rec> extern void ppc_fsubs();
|
||||
template <bool rec> extern void ppc_fmuls();
|
||||
template <bool rec> extern void ppc_fdivs();
|
||||
template <bool rec> extern void ppc_fmadd();
|
||||
template <bool rec> extern void ppc_fmsub();
|
||||
template <bool rec> extern void ppc_fnmadd();
|
||||
template <bool rec> extern void ppc_fnmsub();
|
||||
template <bool rec> extern void ppc_fmadds();
|
||||
template <bool rec> extern void ppc_fmsubs();
|
||||
template <bool rec> extern void ppc_fnmadds();
|
||||
template <bool rec> extern void ppc_fnmsubs();
|
||||
template <bool rec> extern void ppc_fabs();
|
||||
template <bool rec> extern void ppc_fnabs();
|
||||
template <bool rec> extern void ppc_fneg();
|
||||
template <bool rec> extern void ppc_fsel();
|
||||
template <bool rec> extern void ppc_fres();
|
||||
template <bool rec> extern void ppc_fsqrts();
|
||||
template <bool rec> extern void ppc_fsqrt();
|
||||
template <bool rec> extern void ppc_frsqrte();
|
||||
template <bool rec> extern void ppc_frsp();
|
||||
template <bool rec> extern void ppc_fctiw();
|
||||
template <bool rec> extern void ppc_fctiwz();
|
||||
|
||||
extern void ppc_fcmpo();
|
||||
extern void ppc_fcmpu();
|
||||
|
||||
// Power-specific instructions
|
||||
extern void power_abs();
|
||||
template <bool rec, bool ov> extern void power_abs();
|
||||
extern void power_clcs();
|
||||
extern void power_div();
|
||||
extern void power_divs();
|
||||
extern void power_doz();
|
||||
template <bool rec, bool ov> extern void power_div();
|
||||
template <bool rec, bool ov> extern void power_divs();
|
||||
template <bool rec, bool ov> extern void power_doz();
|
||||
extern void power_dozi();
|
||||
extern void power_lscbx();
|
||||
extern void power_maskg();
|
||||
extern void power_maskir();
|
||||
extern void power_mul();
|
||||
extern void power_nabs();
|
||||
template <bool rec> extern void power_lscbx();
|
||||
template <bool rec> extern void power_maskg();
|
||||
template <bool rec> extern void power_maskir();
|
||||
template <bool rec, bool ov> extern void power_mul();
|
||||
template <bool rec, bool ov> extern void power_nabs();
|
||||
extern void power_rlmi();
|
||||
extern void power_rrib();
|
||||
extern void power_sle();
|
||||
extern void power_sleq();
|
||||
extern void power_sliq();
|
||||
extern void power_slliq();
|
||||
extern void power_sllq();
|
||||
extern void power_slq();
|
||||
extern void power_sraiq();
|
||||
extern void power_sraq();
|
||||
extern void power_sre();
|
||||
extern void power_srea();
|
||||
extern void power_sreq();
|
||||
extern void power_sriq();
|
||||
extern void power_srliq();
|
||||
extern void power_srlq();
|
||||
extern void power_srq();
|
||||
template <bool rec> extern void power_rrib();
|
||||
template <bool rec> extern void power_sle();
|
||||
template <bool rec> extern void power_sleq();
|
||||
template <bool rec> extern void power_sliq();
|
||||
template <bool rec> extern void power_slliq();
|
||||
template <bool rec> extern void power_sllq();
|
||||
template <bool rec> extern void power_slq();
|
||||
template <bool rec> extern void power_sraiq();
|
||||
template <bool rec> extern void power_sraq();
|
||||
template <bool rec> extern void power_sre();
|
||||
template <bool rec> extern void power_srea();
|
||||
template <bool rec> extern void power_sreq();
|
||||
template <bool rec> extern void power_sriq();
|
||||
template <bool rec> extern void power_srliq();
|
||||
template <bool rec> extern void power_srlq();
|
||||
template <bool rec> extern void power_srq();
|
||||
} // namespace dppc_interpreter
|
||||
|
||||
// AltiVec instructions
|
||||
|
@ -44,9 +44,6 @@ Po_Cause power_off_reason = po_enter_debugger;
|
||||
|
||||
SetPRS ppc_state;
|
||||
|
||||
bool rc_flag = 0; // Record flag
|
||||
bool oe_flag = 0; // Overflow flag
|
||||
|
||||
bool grab_return;
|
||||
bool grab_breakpoint;
|
||||
|
||||
@ -138,18 +135,28 @@ public:
|
||||
|
||||
/** Primary opcode (bits 0...5) lookup table. */
|
||||
static PPCOpcode OpcodeGrabber[] = {
|
||||
ppc_illegalop, ppc_illegalop, ppc_illegalop, ppc_twi, ppc_illegalop,
|
||||
ppc_illegalop, ppc_illegalop, ppc_mulli, ppc_subfic, power_dozi,
|
||||
ppc_cmpli, ppc_cmpi, ppc_addic, ppc_addicdot, ppc_addi,
|
||||
ppc_addis, ppc_opcode16, ppc_sc, ppc_opcode18, ppc_opcode19<false>,
|
||||
ppc_rlwimi, ppc_rlwinm, power_rlmi, ppc_rlwnm, ppc_ori,
|
||||
ppc_oris, ppc_xori, ppc_xoris, ppc_andidot, ppc_andisdot,
|
||||
ppc_illegalop, ppc_opcode31, ppc_lwz, ppc_lwzu, ppc_lbz,
|
||||
ppc_lbzu, ppc_stw, ppc_stwu, ppc_stb, ppc_stbu,
|
||||
ppc_lhz, ppc_lhzu, ppc_lha, ppc_lhau, ppc_sth,
|
||||
ppc_sthu, ppc_lmw, ppc_stmw, ppc_lfs, ppc_lfsu,
|
||||
ppc_lfd, ppc_lfdu, ppc_stfs, ppc_stfsu, ppc_stfd,
|
||||
ppc_stfdu, ppc_illegalop, ppc_illegalop, ppc_illegalop, ppc_opcode59,
|
||||
ppc_illegalop, ppc_illegalop, ppc_illegalop, ppc_twi,
|
||||
ppc_illegalop, ppc_illegalop, ppc_illegalop, ppc_mulli,
|
||||
ppc_subfic, power_dozi, ppc_cmpli, ppc_cmpi,
|
||||
ppc_addic<false>, ppc_addic<true>,
|
||||
ppc_addi<false>, ppc_addi<true>,
|
||||
ppc_opcode16, ppc_sc, ppc_opcode18, ppc_opcode19<false>,
|
||||
ppc_rlwimi, ppc_rlwinm, power_rlmi, ppc_rlwnm,
|
||||
ppc_ori<false>, ppc_ori<true>,
|
||||
ppc_xori<false>, ppc_xori<true>,
|
||||
ppc_andirc<false>, ppc_andirc<true>,
|
||||
ppc_illegalop, ppc_opcode31,
|
||||
ppc_lz<uint32_t>, ppc_lzu<uint32_t>,
|
||||
ppc_lz<uint8_t>, ppc_lzu<uint8_t>,
|
||||
ppc_st<uint32_t>, ppc_stu<uint32_t>,
|
||||
ppc_st<uint8_t>, ppc_stu<uint8_t>,
|
||||
ppc_lz<uint16_t>, ppc_lzu<uint16_t>,
|
||||
ppc_lha, ppc_lhau,
|
||||
ppc_st<uint16_t>, ppc_stu<uint16_t>,
|
||||
ppc_lmw, ppc_stmw,
|
||||
ppc_lfs, ppc_lfsu, ppc_lfd, ppc_lfdu,
|
||||
ppc_stfs, ppc_stfsu, ppc_stfd, ppc_stfdu,
|
||||
ppc_illegalop, ppc_illegalop, ppc_illegalop, ppc_opcode59,
|
||||
ppc_illegalop, ppc_illegalop, ppc_illegalop, ppc_opcode63
|
||||
};
|
||||
|
||||
@ -169,9 +176,9 @@ static PPCOpcode SubOpcode18Grabber[] = {
|
||||
/** Instructions decoding tables for integer,
|
||||
single floating-point, and double-floating point ops respectively */
|
||||
|
||||
PPCOpcode SubOpcode31Grabber[1024];
|
||||
PPCOpcode SubOpcode59Grabber[32];
|
||||
PPCOpcode SubOpcode63Grabber[1024];
|
||||
PPCOpcode SubOpcode31Grabber[2048];
|
||||
PPCOpcode SubOpcode59Grabber[64];
|
||||
PPCOpcode SubOpcode63Grabber[2048];
|
||||
|
||||
/** Exception helpers. */
|
||||
|
||||
@ -272,21 +279,17 @@ template void ppc_opcode19<false>();
|
||||
template void ppc_opcode19<true>();
|
||||
|
||||
void ppc_opcode31() {
|
||||
uint16_t subop_grab = (ppc_cur_instruction & 0x7FFUL) >> 1UL;
|
||||
rc_flag = ppc_cur_instruction & 0x1;
|
||||
oe_flag = ppc_cur_instruction & 0x400;
|
||||
uint16_t subop_grab = ppc_cur_instruction & 0x7FFUL;
|
||||
SubOpcode31Grabber[subop_grab]();
|
||||
}
|
||||
|
||||
void ppc_opcode59() {
|
||||
uint16_t subop_grab = (ppc_cur_instruction & 0x3EUL) >> 1UL;
|
||||
rc_flag = ppc_cur_instruction & 0x1;
|
||||
uint16_t subop_grab = ppc_cur_instruction & 0x3FUL;
|
||||
SubOpcode59Grabber[subop_grab]();
|
||||
}
|
||||
|
||||
void ppc_opcode63() {
|
||||
uint16_t subop_grab = (ppc_cur_instruction & 0x7FFUL) >> 1UL;
|
||||
rc_flag = ppc_cur_instruction & 0x1;
|
||||
uint16_t subop_grab = ppc_cur_instruction & 0x7FFUL;
|
||||
SubOpcode63Grabber[subop_grab]();
|
||||
}
|
||||
|
||||
@ -578,132 +581,230 @@ void ppc_exec_dbg(volatile uint32_t start_addr, volatile uint32_t size)
|
||||
}
|
||||
|
||||
void initialize_ppc_opcode_tables() {
|
||||
std::fill_n(SubOpcode31Grabber, 1024, ppc_illegalop);
|
||||
std::fill_n(SubOpcode31Grabber, 2048, ppc_illegalop);
|
||||
SubOpcode31Grabber[0] = ppc_cmp;
|
||||
SubOpcode31Grabber[4] = ppc_tw;
|
||||
SubOpcode31Grabber[32] = ppc_cmpl;
|
||||
SubOpcode31Grabber[8] = ppc_tw;
|
||||
SubOpcode31Grabber[64] = ppc_cmpl;
|
||||
|
||||
SubOpcode31Grabber[8] = SubOpcode31Grabber[520] = ppc_subfc;
|
||||
SubOpcode31Grabber[40] = SubOpcode31Grabber[552] = ppc_subf;
|
||||
SubOpcode31Grabber[104] = SubOpcode31Grabber[616] = ppc_neg;
|
||||
SubOpcode31Grabber[136] = SubOpcode31Grabber[648] = ppc_subfe;
|
||||
SubOpcode31Grabber[200] = SubOpcode31Grabber[712] = ppc_subfze;
|
||||
SubOpcode31Grabber[232] = SubOpcode31Grabber[744] = ppc_subfme;
|
||||
SubOpcode31Grabber[16] = ppc_subf<CARRY1, RC0, OV0>;
|
||||
SubOpcode31Grabber[17] = ppc_subf<CARRY1, RC1, OV0>;
|
||||
SubOpcode31Grabber[80] = ppc_subf<CARRY0, RC0, OV0>;
|
||||
SubOpcode31Grabber[81] = ppc_subf<CARRY0, RC1, OV0>;
|
||||
SubOpcode31Grabber[208] = ppc_neg<RC0, OV0>;
|
||||
SubOpcode31Grabber[209] = ppc_neg<RC1, OV0>;
|
||||
SubOpcode31Grabber[272] = ppc_subfe<RC0, OV0>;
|
||||
SubOpcode31Grabber[273] = ppc_subfe<RC1, OV0>;
|
||||
SubOpcode31Grabber[400] = ppc_subfze<RC0, OV0>;
|
||||
SubOpcode31Grabber[401] = ppc_subfze<RC1, OV0>;
|
||||
SubOpcode31Grabber[464] = ppc_subfme<RC0, OV0>;
|
||||
SubOpcode31Grabber[465] = ppc_subfme<RC1, OV0>;
|
||||
|
||||
SubOpcode31Grabber[10] = SubOpcode31Grabber[522] = ppc_addc;
|
||||
SubOpcode31Grabber[138] = SubOpcode31Grabber[650] = ppc_adde;
|
||||
SubOpcode31Grabber[202] = SubOpcode31Grabber[714] = ppc_addze;
|
||||
SubOpcode31Grabber[234] = SubOpcode31Grabber[746] = ppc_addme;
|
||||
SubOpcode31Grabber[266] = SubOpcode31Grabber[778] = ppc_add;
|
||||
SubOpcode31Grabber[1040] = ppc_subf<CARRY1, RC0, OV1>;
|
||||
SubOpcode31Grabber[1041] = ppc_subf<CARRY1, RC1, OV1>;
|
||||
SubOpcode31Grabber[1104] = ppc_subf<CARRY0, RC0, OV1>;
|
||||
SubOpcode31Grabber[1105] = ppc_subf<CARRY0, RC0, OV1>;
|
||||
SubOpcode31Grabber[1232] = ppc_neg<RC0, OV1>;
|
||||
SubOpcode31Grabber[1233] = ppc_neg<RC1, OV1>;
|
||||
SubOpcode31Grabber[1296] = ppc_subfe<RC0, OV1>;
|
||||
SubOpcode31Grabber[1297] = ppc_subfe<RC1, OV1>;
|
||||
SubOpcode31Grabber[1424] = ppc_subfze<RC0, OV1>;
|
||||
SubOpcode31Grabber[1425] = ppc_subfze<RC1, OV1>;
|
||||
SubOpcode31Grabber[464] = ppc_subfme<RC0, OV1>;
|
||||
SubOpcode31Grabber[465] = ppc_subfme<RC1, OV1>;
|
||||
|
||||
SubOpcode31Grabber[11] = ppc_mulhwu;
|
||||
SubOpcode31Grabber[75] = ppc_mulhw;
|
||||
SubOpcode31Grabber[235] = SubOpcode31Grabber[747] = ppc_mullw;
|
||||
SubOpcode31Grabber[459] = SubOpcode31Grabber[971] = ppc_divwu;
|
||||
SubOpcode31Grabber[491] = SubOpcode31Grabber[1003] = ppc_divw;
|
||||
SubOpcode31Grabber[20] = ppc_add<CARRY1, RC0, OV0>;
|
||||
SubOpcode31Grabber[21] = ppc_add<CARRY1, RC1, OV0>;
|
||||
SubOpcode31Grabber[276] = ppc_adde<RC0, OV0>;
|
||||
SubOpcode31Grabber[277] = ppc_adde<RC1, OV0>;
|
||||
SubOpcode31Grabber[404] = ppc_addze<RC0, OV0>;
|
||||
SubOpcode31Grabber[405] = ppc_addze<RC1, OV0>;
|
||||
SubOpcode31Grabber[468] = ppc_addme<RC0, OV0>;
|
||||
SubOpcode31Grabber[469] = ppc_addme<RC1, OV0>;
|
||||
SubOpcode31Grabber[532] = ppc_add<CARRY0, RC0, OV0>;
|
||||
SubOpcode31Grabber[533] = ppc_add<CARRY0, RC1, OV0>;
|
||||
|
||||
SubOpcode31Grabber[20] = ppc_lwarx;
|
||||
SubOpcode31Grabber[23] = ppc_lwzx;
|
||||
SubOpcode31Grabber[55] = ppc_lwzux;
|
||||
SubOpcode31Grabber[87] = ppc_lbzx;
|
||||
SubOpcode31Grabber[119] = ppc_lbzux;
|
||||
SubOpcode31Grabber[279] = ppc_lhzx;
|
||||
SubOpcode31Grabber[311] = ppc_lhzux;
|
||||
SubOpcode31Grabber[343] = ppc_lhax;
|
||||
SubOpcode31Grabber[375] = ppc_lhaux;
|
||||
SubOpcode31Grabber[533] = ppc_lswx;
|
||||
SubOpcode31Grabber[534] = ppc_lwbrx;
|
||||
SubOpcode31Grabber[535] = ppc_lfsx;
|
||||
SubOpcode31Grabber[567] = ppc_lfsux;
|
||||
SubOpcode31Grabber[597] = ppc_lswi;
|
||||
SubOpcode31Grabber[599] = ppc_lfdx;
|
||||
SubOpcode31Grabber[631] = ppc_lfdux;
|
||||
SubOpcode31Grabber[790] = ppc_lhbrx;
|
||||
SubOpcode31Grabber[1044] = ppc_add<CARRY1, RC0, OV1>;
|
||||
SubOpcode31Grabber[1045] = ppc_add<CARRY1, RC1, OV1>;
|
||||
SubOpcode31Grabber[1300] = ppc_adde<RC0, OV1>;
|
||||
SubOpcode31Grabber[1301] = ppc_adde<RC1, OV1>;
|
||||
SubOpcode31Grabber[1428] = ppc_addze<RC0, OV1>;
|
||||
SubOpcode31Grabber[1429] = ppc_addze<RC1, OV1>;
|
||||
SubOpcode31Grabber[1492] = ppc_addme<RC0, OV1>;
|
||||
SubOpcode31Grabber[1493] = ppc_addme<RC1, OV1>;
|
||||
SubOpcode31Grabber[1556] = ppc_add<CARRY0, RC0, OV1>;
|
||||
SubOpcode31Grabber[1557] = ppc_add<CARRY0, RC1, OV1>;
|
||||
|
||||
SubOpcode31Grabber[150] = ppc_stwcx;
|
||||
SubOpcode31Grabber[151] = ppc_stwx;
|
||||
SubOpcode31Grabber[183] = ppc_stwux;
|
||||
SubOpcode31Grabber[215] = ppc_stbx;
|
||||
SubOpcode31Grabber[247] = ppc_stbux;
|
||||
SubOpcode31Grabber[407] = ppc_sthx;
|
||||
SubOpcode31Grabber[439] = ppc_sthux;
|
||||
SubOpcode31Grabber[661] = ppc_stswx;
|
||||
SubOpcode31Grabber[662] = ppc_stwbrx;
|
||||
SubOpcode31Grabber[663] = ppc_stfsx;
|
||||
SubOpcode31Grabber[695] = ppc_stfsux;
|
||||
SubOpcode31Grabber[725] = ppc_stswi;
|
||||
SubOpcode31Grabber[727] = ppc_stfdx;
|
||||
SubOpcode31Grabber[759] = ppc_stfdux;
|
||||
SubOpcode31Grabber[918] = ppc_sthbrx;
|
||||
SubOpcode31Grabber[983] = ppc_stfiwx;
|
||||
SubOpcode31Grabber[22] = ppc_mulhwu<RC0>;
|
||||
SubOpcode31Grabber[23] = ppc_mulhwu<RC1>;
|
||||
SubOpcode31Grabber[150] = ppc_mulhw<RC0>;
|
||||
SubOpcode31Grabber[151] = ppc_mulhw<RC1>;
|
||||
SubOpcode31Grabber[470] = ppc_mullw<RC0, OV0>;
|
||||
SubOpcode31Grabber[471] = ppc_mullw<RC1, OV0>;
|
||||
SubOpcode31Grabber[918] = ppc_divwu<RC0, OV0>;
|
||||
SubOpcode31Grabber[919] = ppc_divwu<RC1, OV0>;
|
||||
SubOpcode31Grabber[982] = ppc_divw<RC0, OV0>;
|
||||
SubOpcode31Grabber[983] = ppc_divw<RC1, OV0>;
|
||||
|
||||
SubOpcode31Grabber[310] = ppc_eciwx;
|
||||
SubOpcode31Grabber[438] = ppc_ecowx;
|
||||
SubOpcode31Grabber[1494] = ppc_mullw<RC0, OV1>;
|
||||
SubOpcode31Grabber[1495] = ppc_mullw<RC1, OV1>;
|
||||
SubOpcode31Grabber[1942] = ppc_divwu<RC0, OV1>;
|
||||
SubOpcode31Grabber[1943] = ppc_divwu<RC1, OV1>;
|
||||
SubOpcode31Grabber[2006] = ppc_divw<RC0, OV0>;
|
||||
SubOpcode31Grabber[2007] = ppc_divw<RC1, OV0>;
|
||||
|
||||
SubOpcode31Grabber[24] = ppc_slw;
|
||||
SubOpcode31Grabber[28] = ppc_and;
|
||||
SubOpcode31Grabber[60] = ppc_andc;
|
||||
SubOpcode31Grabber[124] = ppc_nor;
|
||||
SubOpcode31Grabber[284] = ppc_eqv;
|
||||
SubOpcode31Grabber[316] = ppc_xor;
|
||||
SubOpcode31Grabber[412] = ppc_orc;
|
||||
SubOpcode31Grabber[444] = ppc_or;
|
||||
SubOpcode31Grabber[476] = ppc_nand;
|
||||
SubOpcode31Grabber[536] = ppc_srw;
|
||||
SubOpcode31Grabber[792] = ppc_sraw;
|
||||
SubOpcode31Grabber[824] = ppc_srawi;
|
||||
SubOpcode31Grabber[922] = ppc_extsh;
|
||||
SubOpcode31Grabber[954] = ppc_extsb;
|
||||
SubOpcode31Grabber[40] = ppc_lwarx;
|
||||
SubOpcode31Grabber[46] = ppc_lzx<uint32_t>;
|
||||
SubOpcode31Grabber[110] = ppc_lzux<uint32_t>;
|
||||
SubOpcode31Grabber[174] = ppc_lzx<uint8_t>;
|
||||
SubOpcode31Grabber[238] = ppc_lzux<uint8_t>;
|
||||
SubOpcode31Grabber[558] = ppc_lzx<uint16_t>;
|
||||
SubOpcode31Grabber[662] = ppc_lzux<uint16_t>;
|
||||
SubOpcode31Grabber[686] = ppc_lhax;
|
||||
SubOpcode31Grabber[750] = ppc_lhaux;
|
||||
SubOpcode31Grabber[1066] = ppc_lswx;
|
||||
SubOpcode31Grabber[1068] = ppc_lwbrx;
|
||||
SubOpcode31Grabber[1070] = ppc_lfsx;
|
||||
SubOpcode31Grabber[1134] = ppc_lfsux;
|
||||
SubOpcode31Grabber[1194] = ppc_lswi;
|
||||
SubOpcode31Grabber[1198] = ppc_lfdx;
|
||||
SubOpcode31Grabber[1262] = ppc_lfdux;
|
||||
SubOpcode31Grabber[1580] = ppc_lhbrx;
|
||||
|
||||
SubOpcode31Grabber[26] = ppc_cntlzw;
|
||||
SubOpcode31Grabber[301] = ppc_stwcx;
|
||||
SubOpcode31Grabber[302] = ppc_stx<uint32_t>;
|
||||
SubOpcode31Grabber[366] = ppc_stux<uint32_t>;
|
||||
SubOpcode31Grabber[430] = ppc_stx<uint8_t>;
|
||||
SubOpcode31Grabber[494] = ppc_stux<uint8_t>;
|
||||
SubOpcode31Grabber[814] = ppc_stx<uint16_t>;
|
||||
SubOpcode31Grabber[878] = ppc_stux<uint16_t>;
|
||||
SubOpcode31Grabber[1322] = ppc_stswx;
|
||||
SubOpcode31Grabber[1324] = ppc_stwbrx;
|
||||
SubOpcode31Grabber[1326] = ppc_stfsx;
|
||||
SubOpcode31Grabber[1390] = ppc_stfsux;
|
||||
SubOpcode31Grabber[1450] = ppc_stswi;
|
||||
SubOpcode31Grabber[1454] = ppc_stfdx;
|
||||
SubOpcode31Grabber[1518] = ppc_stfdux;
|
||||
SubOpcode31Grabber[1836] = ppc_sthbrx;
|
||||
SubOpcode31Grabber[1966] = ppc_stfiwx;
|
||||
|
||||
SubOpcode31Grabber[19] = ppc_mfcr;
|
||||
SubOpcode31Grabber[83] = ppc_mfmsr;
|
||||
SubOpcode31Grabber[144] = ppc_mtcrf;
|
||||
SubOpcode31Grabber[146] = ppc_mtmsr;
|
||||
SubOpcode31Grabber[210] = ppc_mtsr;
|
||||
SubOpcode31Grabber[242] = ppc_mtsrin;
|
||||
SubOpcode31Grabber[339] = ppc_mfspr;
|
||||
SubOpcode31Grabber[371] = ppc_mftb;
|
||||
SubOpcode31Grabber[467] = ppc_mtspr;
|
||||
SubOpcode31Grabber[512] = ppc_mcrxr;
|
||||
SubOpcode31Grabber[595] = ppc_mfsr;
|
||||
SubOpcode31Grabber[659] = ppc_mfsrin;
|
||||
SubOpcode31Grabber[620] = ppc_eciwx;
|
||||
SubOpcode31Grabber[876] = ppc_ecowx;
|
||||
|
||||
SubOpcode31Grabber[54] = ppc_dcbst;
|
||||
SubOpcode31Grabber[86] = ppc_dcbf;
|
||||
SubOpcode31Grabber[246] = ppc_dcbtst;
|
||||
SubOpcode31Grabber[278] = ppc_dcbt;
|
||||
SubOpcode31Grabber[598] = ppc_sync;
|
||||
SubOpcode31Grabber[470] = ppc_dcbi;
|
||||
SubOpcode31Grabber[1014] = ppc_dcbz;
|
||||
SubOpcode31Grabber[48] = ppc_shift<LSHFT, RC0>;
|
||||
SubOpcode31Grabber[49] = ppc_shift<LSHFT, RC1>;
|
||||
SubOpcode31Grabber[56] = ppc_do_bool<bool_and, RC0>;
|
||||
SubOpcode31Grabber[57] = ppc_do_bool<bool_and, RC1>;
|
||||
SubOpcode31Grabber[120] = ppc_do_bool<bool_andc, RC0>;
|
||||
SubOpcode31Grabber[121] = ppc_do_bool<bool_andc, RC1>;
|
||||
SubOpcode31Grabber[248] = ppc_do_bool<bool_nor, RC0>;
|
||||
SubOpcode31Grabber[249] = ppc_do_bool<bool_nor, RC1>;
|
||||
SubOpcode31Grabber[568] = ppc_do_bool<bool_eqv, RC0>;
|
||||
SubOpcode31Grabber[569] = ppc_do_bool<bool_eqv, RC1>;
|
||||
SubOpcode31Grabber[632] = ppc_do_bool<bool_xor, RC0>;
|
||||
SubOpcode31Grabber[633] = ppc_do_bool<bool_xor, RC1>;
|
||||
SubOpcode31Grabber[824] = ppc_do_bool<bool_orc, RC0>;
|
||||
SubOpcode31Grabber[825] = ppc_do_bool<bool_orc, RC1>;
|
||||
SubOpcode31Grabber[888] = ppc_do_bool<bool_or, RC0>;
|
||||
SubOpcode31Grabber[889] = ppc_do_bool<bool_or, RC1>;
|
||||
SubOpcode31Grabber[1072] = ppc_shift<RSHFT, RC0>;
|
||||
SubOpcode31Grabber[1073] = ppc_shift<RSHFT, RC1>;
|
||||
SubOpcode31Grabber[1584] = ppc_sraw<RC0>;
|
||||
SubOpcode31Grabber[1585] = ppc_sraw<RC1>;
|
||||
SubOpcode31Grabber[1648] = ppc_srawi<RC0>;
|
||||
SubOpcode31Grabber[1649] = ppc_srawi<RC1>;
|
||||
SubOpcode31Grabber[1844] = ppc_exts<int8_t, RC0>;
|
||||
SubOpcode31Grabber[1845] = ppc_exts<int8_t, RC1>;
|
||||
SubOpcode31Grabber[1908] = ppc_exts<int16_t, RC0>;
|
||||
SubOpcode31Grabber[1909] = ppc_exts<int16_t, RC1>;
|
||||
|
||||
SubOpcode31Grabber[29] = power_maskg;
|
||||
SubOpcode31Grabber[107] = SubOpcode31Grabber[619] = power_mul;
|
||||
SubOpcode31Grabber[152] = power_slq;
|
||||
SubOpcode31Grabber[153] = power_sle;
|
||||
SubOpcode31Grabber[184] = power_sliq;
|
||||
SubOpcode31Grabber[216] = power_sllq;
|
||||
SubOpcode31Grabber[217] = power_sleq;
|
||||
SubOpcode31Grabber[248] = power_slliq;
|
||||
SubOpcode31Grabber[264] = SubOpcode31Grabber[776] = power_doz;
|
||||
SubOpcode31Grabber[277] = power_lscbx;
|
||||
SubOpcode31Grabber[331] = SubOpcode31Grabber[843] = power_div;
|
||||
SubOpcode31Grabber[360] = SubOpcode31Grabber[872] = power_abs;
|
||||
SubOpcode31Grabber[363] = SubOpcode31Grabber[875] = power_divs;
|
||||
SubOpcode31Grabber[488] = SubOpcode31Grabber[1000] = power_nabs;
|
||||
SubOpcode31Grabber[531] = power_clcs;
|
||||
SubOpcode31Grabber[537] = power_rrib;
|
||||
SubOpcode31Grabber[541] = power_maskir;
|
||||
SubOpcode31Grabber[664] = power_srq;
|
||||
SubOpcode31Grabber[665] = power_sre;
|
||||
SubOpcode31Grabber[696] = power_sriq;
|
||||
SubOpcode31Grabber[728] = power_srlq;
|
||||
SubOpcode31Grabber[729] = power_sreq;
|
||||
SubOpcode31Grabber[760] = power_srliq;
|
||||
SubOpcode31Grabber[920] = power_sraq;
|
||||
SubOpcode31Grabber[921] = power_srea;
|
||||
SubOpcode31Grabber[952] = power_sraiq;
|
||||
SubOpcode31Grabber[52] = ppc_cntlzw<RC0>;
|
||||
SubOpcode31Grabber[53] = ppc_cntlzw<RC1>;
|
||||
|
||||
SubOpcode31Grabber[38] = ppc_mfcr;
|
||||
SubOpcode31Grabber[166] = ppc_mfmsr;
|
||||
SubOpcode31Grabber[144] = ppc_mtcrf;
|
||||
SubOpcode31Grabber[292] = ppc_mtmsr;
|
||||
SubOpcode31Grabber[420] = ppc_mtsr;
|
||||
SubOpcode31Grabber[484] = ppc_mtsrin;
|
||||
SubOpcode31Grabber[678] = ppc_mfspr;
|
||||
SubOpcode31Grabber[742] = ppc_mftb;
|
||||
SubOpcode31Grabber[934] = ppc_mtspr;
|
||||
SubOpcode31Grabber[1024] = ppc_mcrxr;
|
||||
SubOpcode31Grabber[1190] = ppc_mfsr;
|
||||
SubOpcode31Grabber[1318] = ppc_mfsrin;
|
||||
|
||||
SubOpcode31Grabber[108] = ppc_dcbst;
|
||||
SubOpcode31Grabber[172] = ppc_dcbf;
|
||||
SubOpcode31Grabber[492] = ppc_dcbtst;
|
||||
SubOpcode31Grabber[556] = ppc_dcbt;
|
||||
SubOpcode31Grabber[940] = ppc_dcbi;
|
||||
SubOpcode31Grabber[1196] = ppc_sync;
|
||||
SubOpcode31Grabber[2028] = ppc_dcbz;
|
||||
|
||||
SubOpcode31Grabber[58] = power_maskg<RC0>;
|
||||
SubOpcode31Grabber[59] = power_maskg<RC1>;
|
||||
SubOpcode31Grabber[214] = power_mul<RC0, OV0>;
|
||||
SubOpcode31Grabber[215] = power_mul<RC1, OV0>;
|
||||
SubOpcode31Grabber[304] = power_slq<RC0>;
|
||||
SubOpcode31Grabber[305] = power_slq<RC1>;
|
||||
SubOpcode31Grabber[306] = power_sle<RC0>;
|
||||
SubOpcode31Grabber[306] = power_sle<RC1>;
|
||||
SubOpcode31Grabber[368] = power_sliq<RC0>;
|
||||
SubOpcode31Grabber[369] = power_sliq<RC1>;
|
||||
SubOpcode31Grabber[432] = power_sllq<RC0>;
|
||||
SubOpcode31Grabber[433] = power_sllq<RC1>;
|
||||
SubOpcode31Grabber[434] = power_sleq<RC0>;
|
||||
SubOpcode31Grabber[435] = power_sleq<RC1>;
|
||||
SubOpcode31Grabber[496] = power_slliq<RC0>;
|
||||
SubOpcode31Grabber[497] = power_slliq<RC1>;
|
||||
SubOpcode31Grabber[528] = power_doz<RC0, OV0>;
|
||||
SubOpcode31Grabber[529] = power_doz<RC1, OV0>;
|
||||
SubOpcode31Grabber[554] = power_lscbx<RC0>;
|
||||
SubOpcode31Grabber[555] = power_lscbx<RC1>;
|
||||
SubOpcode31Grabber[662] = power_div<RC0, OV0>;
|
||||
SubOpcode31Grabber[663] = power_div<RC1, OV0>;
|
||||
SubOpcode31Grabber[720] = power_abs<RC0, OV0>;
|
||||
SubOpcode31Grabber[721] = power_abs<RC1, OV0>;
|
||||
SubOpcode31Grabber[726] = power_divs<RC0, OV0>;
|
||||
SubOpcode31Grabber[727] = power_divs<RC1, OV0>;
|
||||
SubOpcode31Grabber[976] = power_nabs<RC0, OV0>;
|
||||
SubOpcode31Grabber[977] = power_nabs<RC1, OV0>;
|
||||
SubOpcode31Grabber[1062] = power_clcs;
|
||||
SubOpcode31Grabber[1074] = power_rrib<RC0>;
|
||||
SubOpcode31Grabber[1075] = power_rrib<RC1>;
|
||||
SubOpcode31Grabber[1082] = power_maskir<RC0>;
|
||||
SubOpcode31Grabber[1083] = power_maskir<RC1>;
|
||||
SubOpcode31Grabber[1328] = power_srq<RC0>;
|
||||
SubOpcode31Grabber[1329] = power_srq<RC1>;
|
||||
SubOpcode31Grabber[1330] = power_sre<RC0>;
|
||||
SubOpcode31Grabber[1331] = power_sre<RC1>;
|
||||
SubOpcode31Grabber[1332] = power_sriq<RC0>;
|
||||
SubOpcode31Grabber[1333] = power_sriq<RC1>;
|
||||
SubOpcode31Grabber[1456] = power_srlq<RC0>;
|
||||
SubOpcode31Grabber[1457] = power_srlq<RC1>;
|
||||
SubOpcode31Grabber[1458] = power_sreq<RC0>;
|
||||
SubOpcode31Grabber[1459] = power_sreq<RC1>;
|
||||
SubOpcode31Grabber[1520] = power_srliq<RC0>;
|
||||
SubOpcode31Grabber[1521] = power_srliq<RC1>;
|
||||
SubOpcode31Grabber[1840] = power_sraq<RC0>;
|
||||
SubOpcode31Grabber[1841] = power_sraq<RC1>;
|
||||
SubOpcode31Grabber[1842] = power_srea<RC0>;
|
||||
SubOpcode31Grabber[1843] = power_srea<RC1>;
|
||||
SubOpcode31Grabber[1904] = power_sraiq<RC0>;
|
||||
SubOpcode31Grabber[1905] = power_sraiq<RC1>;
|
||||
|
||||
SubOpcode31Grabber[1238] = power_mul<RC0, OV1>;
|
||||
SubOpcode31Grabber[1239] = power_mul<RC1, OV1>;
|
||||
SubOpcode31Grabber[1552] = power_doz<RC0, OV1>;
|
||||
SubOpcode31Grabber[1553] = power_doz<RC1, OV1>;
|
||||
SubOpcode31Grabber[1686] = power_div<RC0, OV1>;
|
||||
SubOpcode31Grabber[1687] = power_div<RC1, OV1>;
|
||||
SubOpcode31Grabber[1744] = power_abs<RC0, OV1>;
|
||||
SubOpcode31Grabber[1745] = power_abs<RC1, OV1>;
|
||||
SubOpcode31Grabber[1750] = power_divs<RC0, OV1>;
|
||||
SubOpcode31Grabber[1751] = power_divs<RC1, OV1>;
|
||||
SubOpcode31Grabber[2000] = power_nabs<RC0, OV1>;
|
||||
SubOpcode31Grabber[2001] = power_nabs<RC1, OV1>;
|
||||
|
||||
SubOpcode31Grabber[306] = ppc_tlbie;
|
||||
SubOpcode31Grabber[370] = ppc_tlbia;
|
||||
@ -713,47 +814,80 @@ void initialize_ppc_opcode_tables() {
|
||||
SubOpcode31Grabber[978] = ppc_tlbld;
|
||||
SubOpcode31Grabber[1010] = ppc_tlbli;
|
||||
|
||||
std::fill_n(SubOpcode59Grabber, 32, ppc_illegalop);
|
||||
SubOpcode59Grabber[18] = ppc_fdivs;
|
||||
SubOpcode59Grabber[20] = ppc_fsubs;
|
||||
SubOpcode59Grabber[21] = ppc_fadds;
|
||||
SubOpcode59Grabber[22] = ppc_fsqrts;
|
||||
SubOpcode59Grabber[24] = ppc_fres;
|
||||
SubOpcode59Grabber[25] = ppc_fmuls;
|
||||
SubOpcode59Grabber[28] = ppc_fmsubs;
|
||||
SubOpcode59Grabber[29] = ppc_fmadds;
|
||||
SubOpcode59Grabber[30] = ppc_fnmsubs;
|
||||
SubOpcode59Grabber[31] = ppc_fnmadds;
|
||||
std::fill_n(SubOpcode59Grabber, 64, ppc_illegalop);
|
||||
SubOpcode59Grabber[36] = ppc_fdivs<RC0>;
|
||||
SubOpcode59Grabber[37] = ppc_fdivs<RC1>;
|
||||
SubOpcode59Grabber[40] = ppc_fsubs<RC0>;
|
||||
SubOpcode59Grabber[41] = ppc_fsubs<RC1>;
|
||||
SubOpcode59Grabber[42] = ppc_fadds<RC0>;
|
||||
SubOpcode59Grabber[43] = ppc_fadds<RC1>;
|
||||
SubOpcode59Grabber[44] = ppc_fsqrts<RC0>;
|
||||
SubOpcode59Grabber[45] = ppc_fsqrts<RC1>;
|
||||
SubOpcode59Grabber[48] = ppc_fres<RC0>;
|
||||
SubOpcode59Grabber[49] = ppc_fres<RC1>;
|
||||
SubOpcode59Grabber[50] = ppc_fmuls<RC0>;
|
||||
SubOpcode59Grabber[51] = ppc_fmuls<RC1>;
|
||||
SubOpcode59Grabber[56] = ppc_fmsubs<RC0>;
|
||||
SubOpcode59Grabber[57] = ppc_fmsubs<RC1>;
|
||||
SubOpcode59Grabber[58] = ppc_fmadds<RC0>;
|
||||
SubOpcode59Grabber[59] = ppc_fmadds<RC1>;
|
||||
SubOpcode59Grabber[60] = ppc_fnmsubs<RC0>;
|
||||
SubOpcode59Grabber[61] = ppc_fnmsubs<RC1>;
|
||||
SubOpcode59Grabber[62] = ppc_fnmadds<RC0>;
|
||||
SubOpcode59Grabber[63] = ppc_fnmadds<RC1>;
|
||||
|
||||
std::fill_n(SubOpcode63Grabber, 1024, ppc_illegalop);
|
||||
SubOpcode63Grabber[0] = ppc_fcmpu;
|
||||
SubOpcode63Grabber[12] = ppc_frsp;
|
||||
SubOpcode63Grabber[14] = ppc_fctiw;
|
||||
SubOpcode63Grabber[15] = ppc_fctiwz;
|
||||
SubOpcode63Grabber[18] = ppc_fdiv;
|
||||
SubOpcode63Grabber[20] = ppc_fsub;
|
||||
SubOpcode63Grabber[21] = ppc_fadd;
|
||||
SubOpcode63Grabber[22] = ppc_fsqrt;
|
||||
SubOpcode63Grabber[26] = ppc_frsqrte;
|
||||
SubOpcode63Grabber[32] = ppc_fcmpo;
|
||||
SubOpcode63Grabber[38] = ppc_mtfsb1;
|
||||
SubOpcode63Grabber[40] = ppc_fneg;
|
||||
SubOpcode63Grabber[64] = ppc_mcrfs;
|
||||
SubOpcode63Grabber[70] = ppc_mtfsb0;
|
||||
SubOpcode63Grabber[72] = ppc_fmr;
|
||||
SubOpcode63Grabber[134] = ppc_mtfsfi;
|
||||
SubOpcode63Grabber[136] = ppc_fnabs;
|
||||
SubOpcode63Grabber[264] = ppc_fabs;
|
||||
SubOpcode63Grabber[583] = ppc_mffs<false>;
|
||||
SubOpcode63Grabber[711] = ppc_mtfsf;
|
||||
std::fill_n(SubOpcode63Grabber, 2048, ppc_illegalop);
|
||||
SubOpcode63Grabber[0] = ppc_fcmpu;
|
||||
SubOpcode63Grabber[24] = ppc_frsp<RC0>;
|
||||
SubOpcode63Grabber[25] = ppc_frsp<RC1>;
|
||||
SubOpcode63Grabber[28] = ppc_fctiw<RC0>;
|
||||
SubOpcode63Grabber[29] = ppc_fctiw<RC1>;
|
||||
SubOpcode63Grabber[30] = ppc_fctiwz<RC0>;
|
||||
SubOpcode63Grabber[31] = ppc_fctiwz<RC1>;
|
||||
SubOpcode63Grabber[36] = ppc_fdiv<RC0>;
|
||||
SubOpcode63Grabber[37] = ppc_fdiv<RC1>;
|
||||
SubOpcode63Grabber[40] = ppc_fsub<RC0>;
|
||||
SubOpcode63Grabber[41] = ppc_fsub<RC1>;
|
||||
SubOpcode63Grabber[42] = ppc_fadd<RC0>;
|
||||
SubOpcode63Grabber[43] = ppc_fadd<RC1>;
|
||||
SubOpcode63Grabber[44] = ppc_fsqrt<RC0>;
|
||||
SubOpcode63Grabber[45] = ppc_fsqrt<RC1>;
|
||||
SubOpcode63Grabber[52] = ppc_frsqrte<RC0>;
|
||||
SubOpcode63Grabber[53] = ppc_frsqrte<RC1>;
|
||||
SubOpcode63Grabber[64] = ppc_fcmpo;
|
||||
SubOpcode63Grabber[76] = ppc_mtfsb1<RC0>;
|
||||
SubOpcode63Grabber[77] = ppc_mtfsb1<RC1>;
|
||||
SubOpcode63Grabber[80] = ppc_fneg<RC0>;
|
||||
SubOpcode63Grabber[81] = ppc_fneg<RC1>;
|
||||
SubOpcode63Grabber[128] = ppc_mcrfs;
|
||||
SubOpcode63Grabber[140] = ppc_mtfsb0<RC0>;
|
||||
SubOpcode63Grabber[141] = ppc_mtfsb0<RC1>;
|
||||
SubOpcode63Grabber[144] = ppc_fmr<RC0>;
|
||||
SubOpcode63Grabber[145] = ppc_fmr<RC1>;
|
||||
SubOpcode63Grabber[268] = ppc_mtfsfi<RC0>;
|
||||
SubOpcode63Grabber[269] = ppc_mtfsfi<RC1>;
|
||||
SubOpcode63Grabber[272] = ppc_fnabs<RC0>;
|
||||
SubOpcode63Grabber[273] = ppc_fnabs<RC1>;
|
||||
SubOpcode63Grabber[528] = ppc_fabs<RC0>;
|
||||
SubOpcode63Grabber[529] = ppc_fabs<RC1>;
|
||||
SubOpcode63Grabber[1166] = ppc_mffs<IS601, RC0>;
|
||||
SubOpcode63Grabber[1167] = ppc_mffs<IS601, RC1>;
|
||||
SubOpcode63Grabber[1422] = ppc_mtfsf<RC0>;
|
||||
SubOpcode63Grabber[1423] = ppc_mtfsf<RC1>;
|
||||
|
||||
for (int i = 0; i < 1024; i += 32) {
|
||||
SubOpcode63Grabber[i + 23] = ppc_fsel;
|
||||
SubOpcode63Grabber[i + 25] = ppc_fmul;
|
||||
SubOpcode63Grabber[i + 28] = ppc_fmsub;
|
||||
SubOpcode63Grabber[i + 29] = ppc_fmadd;
|
||||
SubOpcode63Grabber[i + 30] = ppc_fnmsub;
|
||||
SubOpcode63Grabber[i + 31] = ppc_fnmadd;
|
||||
for (int i = 0; i < 2048; i += 64) {
|
||||
SubOpcode63Grabber[i + 46] = ppc_fsel<RC0>;
|
||||
SubOpcode63Grabber[i + 47] = ppc_fsel<RC1>;
|
||||
SubOpcode63Grabber[i + 50] = ppc_fmul<RC0>;
|
||||
SubOpcode63Grabber[i + 50] = ppc_fmul<RC1>;
|
||||
SubOpcode63Grabber[i + 56] = ppc_fmsub<RC0>;
|
||||
SubOpcode63Grabber[i + 57] = ppc_fmsub<RC1>;
|
||||
SubOpcode63Grabber[i + 58] = ppc_fmadd<RC0>;
|
||||
SubOpcode63Grabber[i + 59] = ppc_fmadd<RC1>;
|
||||
SubOpcode63Grabber[i + 60] = ppc_fnmsub<RC0>;
|
||||
SubOpcode63Grabber[i + 61] = ppc_fnmsub<RC1>;
|
||||
SubOpcode63Grabber[i + 62] = ppc_fnmadd<RC0>;
|
||||
SubOpcode63Grabber[i + 63] = ppc_fnmadd<RC1>;
|
||||
}
|
||||
}
|
||||
|
||||
@ -777,19 +911,23 @@ void ppc_cpu_init(MemCtrlBase* mem_ctrl, uint32_t cpu_version, uint64_t tb_freq)
|
||||
initialize_ppc_opcode_tables();
|
||||
|
||||
if (cpu_version == PPC_VER::MPC601) {
|
||||
OpcodeGrabber[19] = ppc_opcode19<true>;
|
||||
SubOpcode31Grabber[370] = ppc_illegalop; // tlbia
|
||||
SubOpcode31Grabber[371] = ppc_illegalop; // mftb
|
||||
SubOpcode59Grabber[24] = ppc_illegalop; // fres
|
||||
SubOpcode63Grabber[26] = ppc_illegalop; // frsqrte
|
||||
SubOpcode63Grabber[583] = ppc_mffs<true>;
|
||||
for (int i = 0; i < 1024; i += 32) {
|
||||
SubOpcode63Grabber[i + 23] = ppc_illegalop; // fsel
|
||||
OpcodeGrabber[19] = ppc_opcode19<IS601>;
|
||||
SubOpcode31Grabber[740] = ppc_illegalop; // tlbia
|
||||
SubOpcode31Grabber[742] = ppc_illegalop; // mftb
|
||||
SubOpcode59Grabber[48] = ppc_illegalop; // fres
|
||||
SubOpcode63Grabber[52] = ppc_illegalop; // frsqrte
|
||||
SubOpcode63Grabber[1166] = ppc_mffs<IS601, RC0>;
|
||||
SubOpcode63Grabber[1167] = ppc_mffs<IS601, RC1>;
|
||||
for (int i = 0; i < 2048; i += 64) {
|
||||
SubOpcode63Grabber[i + 46] = ppc_illegalop; // fsel
|
||||
SubOpcode63Grabber[i + 47] = ppc_illegalop; // fsel.
|
||||
}
|
||||
}
|
||||
if (cpu_version != PPC_VER::MPC970MP) {
|
||||
SubOpcode59Grabber[22] = ppc_illegalop; // fsqrts
|
||||
SubOpcode63Grabber[22] = ppc_illegalop; // fsqrt
|
||||
SubOpcode59Grabber[44] = ppc_illegalop; // fsqrts
|
||||
SubOpcode59Grabber[45] = ppc_illegalop; // fsqrts.
|
||||
SubOpcode63Grabber[44] = ppc_illegalop; // fsqrt
|
||||
SubOpcode63Grabber[45] = ppc_illegalop; // fsqrt.
|
||||
}
|
||||
|
||||
// initialize emulator timers
|
||||
|
@ -96,7 +96,7 @@ void update_fex() {
|
||||
}
|
||||
|
||||
template <const FPOP fpop>
|
||||
void ppc_confirm_inf_nan(int chosen_reg_1, int chosen_reg_2, bool rc_flag = false) {
|
||||
void ppc_confirm_inf_nan(int chosen_reg_1, int chosen_reg_2, bool rec = false) {
|
||||
double input_a = ppc_state.fpr[chosen_reg_1].dbl64_r;
|
||||
double input_b = ppc_state.fpr[chosen_reg_2].dbl64_r;
|
||||
|
||||
@ -160,145 +160,178 @@ static void fpresult_update(double set_result) {
|
||||
}
|
||||
|
||||
// Floating Point Arithmetic
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fadd() {
|
||||
ppc_grab_regsfpdab(ppc_cur_instruction);
|
||||
|
||||
if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) {
|
||||
ppc_state.fpscr |= FPCC_FUNAN;
|
||||
ppc_confirm_inf_nan<ADD>(reg_a, reg_b, rc_flag);
|
||||
ppc_confirm_inf_nan<ADD>(reg_a, reg_b, rec);
|
||||
}
|
||||
|
||||
double ppc_dblresult64_d = val_reg_a + val_reg_b;
|
||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
fpresult_update(ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fadd<RC0>();
|
||||
template void dppc_interpreter::ppc_fadd<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fsub() {
|
||||
ppc_grab_regsfpdab(ppc_cur_instruction);
|
||||
|
||||
if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) {
|
||||
ppc_state.fpscr |= FPCC_FUNAN;
|
||||
ppc_confirm_inf_nan<SUB>(reg_a, reg_b, rc_flag);
|
||||
ppc_confirm_inf_nan<SUB>(reg_a, reg_b, rec);
|
||||
}
|
||||
|
||||
double ppc_dblresult64_d = val_reg_a - val_reg_b;
|
||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
fpresult_update(ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fsub<RC0>();
|
||||
template void dppc_interpreter::ppc_fsub<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fdiv() {
|
||||
ppc_grab_regsfpdab(ppc_cur_instruction);
|
||||
|
||||
if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) {
|
||||
ppc_confirm_inf_nan<DIV>(reg_a, reg_b, rc_flag);
|
||||
ppc_confirm_inf_nan<DIV>(reg_a, reg_b, rec);
|
||||
}
|
||||
|
||||
double ppc_dblresult64_d = val_reg_a / val_reg_b;
|
||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
fpresult_update(ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fdiv<RC0>();
|
||||
template void dppc_interpreter::ppc_fdiv<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fmul() {
|
||||
ppc_grab_regsfpdac(ppc_cur_instruction);
|
||||
|
||||
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
|
||||
ppc_confirm_inf_nan<MUL>(reg_a, reg_c, rc_flag);
|
||||
ppc_confirm_inf_nan<MUL>(reg_a, reg_c, rec);
|
||||
}
|
||||
|
||||
double ppc_dblresult64_d = val_reg_a * val_reg_c;
|
||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
fpresult_update(ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fmul<RC0>();
|
||||
template void dppc_interpreter::ppc_fmul<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fmadd() {
|
||||
ppc_grab_regsfpdabc(ppc_cur_instruction);
|
||||
|
||||
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
|
||||
ppc_confirm_inf_nan<MUL>(reg_a, reg_c, rc_flag);
|
||||
ppc_confirm_inf_nan<MUL>(reg_a, reg_c, rec);
|
||||
}
|
||||
if (std::isnan(val_reg_b)) {
|
||||
ppc_confirm_inf_nan<ADD>(reg_a, reg_b, rc_flag);
|
||||
ppc_confirm_inf_nan<ADD>(reg_a, reg_b, rec);
|
||||
}
|
||||
|
||||
double ppc_dblresult64_d = std::fma(val_reg_a, val_reg_c, val_reg_b);
|
||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
fpresult_update(ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fmadd<RC0>();
|
||||
template void dppc_interpreter::ppc_fmadd<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fmsub() {
|
||||
ppc_grab_regsfpdabc(ppc_cur_instruction);
|
||||
|
||||
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
|
||||
ppc_confirm_inf_nan<MUL>(reg_a, reg_c, rc_flag);
|
||||
ppc_confirm_inf_nan<MUL>(reg_a, reg_c, rec);
|
||||
}
|
||||
if (std::isnan(val_reg_b)) {
|
||||
ppc_confirm_inf_nan<SUB>(reg_a, reg_b, rc_flag);
|
||||
ppc_confirm_inf_nan<SUB>(reg_a, reg_b, rec);
|
||||
}
|
||||
|
||||
double ppc_dblresult64_d = std::fma(val_reg_a, val_reg_c, -val_reg_b);
|
||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
fpresult_update(ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fmsub<RC0>();
|
||||
template void dppc_interpreter::ppc_fmsub<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fnmadd() {
|
||||
ppc_grab_regsfpdabc(ppc_cur_instruction);
|
||||
|
||||
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
|
||||
ppc_confirm_inf_nan<MUL>(reg_a, reg_c, rc_flag);
|
||||
ppc_confirm_inf_nan<MUL>(reg_a, reg_c, rec);
|
||||
}
|
||||
if (std::isnan(val_reg_b)) {
|
||||
ppc_confirm_inf_nan<ADD>(reg_a, reg_b, rc_flag);
|
||||
ppc_confirm_inf_nan<ADD>(reg_a, reg_b, rec);
|
||||
}
|
||||
|
||||
double ppc_dblresult64_d = -std::fma(val_reg_a, val_reg_c, val_reg_b);
|
||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
fpresult_update(ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fnmadd<RC0>();
|
||||
template void dppc_interpreter::ppc_fnmadd<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fnmsub() {
|
||||
ppc_grab_regsfpdabc(ppc_cur_instruction);
|
||||
|
||||
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
|
||||
ppc_confirm_inf_nan<MUL>(reg_a, reg_c, rc_flag);
|
||||
ppc_confirm_inf_nan<MUL>(reg_a, reg_c, rec);
|
||||
}
|
||||
if (std::isnan(val_reg_b)) {
|
||||
ppc_confirm_inf_nan<SUB>(reg_a, reg_b, rc_flag);
|
||||
ppc_confirm_inf_nan<SUB>(reg_a, reg_b, rec);
|
||||
}
|
||||
|
||||
double ppc_dblresult64_d = std::fma(-val_reg_a, val_reg_c, val_reg_b);
|
||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
fpresult_update(ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fnmsub<RC0>();
|
||||
template void dppc_interpreter::ppc_fnmsub<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fadds() {
|
||||
ppc_grab_regsfpdab(ppc_cur_instruction);
|
||||
|
||||
if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) {
|
||||
ppc_confirm_inf_nan<ADD>(reg_a, reg_b, rc_flag);
|
||||
ppc_confirm_inf_nan<ADD>(reg_a, reg_b, rec);
|
||||
}
|
||||
|
||||
float ppc_fltresult32_d = val_reg_a + val_reg_b;
|
||||
@ -307,127 +340,159 @@ void dppc_interpreter::ppc_fadds() {
|
||||
|
||||
fpresult_update(ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fadds<RC0>();
|
||||
template void dppc_interpreter::ppc_fadds<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fsubs() {
|
||||
ppc_grab_regsfpdab(ppc_cur_instruction);
|
||||
|
||||
if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) {
|
||||
ppc_confirm_inf_nan<SUB>(reg_a, reg_b, rc_flag);
|
||||
ppc_confirm_inf_nan<SUB>(reg_a, reg_b, rec);
|
||||
}
|
||||
|
||||
double ppc_dblresult64_d = (float)(val_reg_a - val_reg_b);
|
||||
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
fpresult_update(ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fsubs<RC0>();
|
||||
template void dppc_interpreter::ppc_fsubs<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fdivs() {
|
||||
ppc_grab_regsfpdab(ppc_cur_instruction);
|
||||
|
||||
if (std::isnan(val_reg_a) || std::isnan(val_reg_b)) {
|
||||
ppc_confirm_inf_nan<DIV>(reg_a, reg_b, rc_flag);
|
||||
ppc_confirm_inf_nan<DIV>(reg_a, reg_b, rec);
|
||||
}
|
||||
|
||||
double ppc_dblresult64_d = (float)(val_reg_a / val_reg_b);
|
||||
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
fpresult_update(ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fdivs<RC0>();
|
||||
template void dppc_interpreter::ppc_fdivs<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fmuls() {
|
||||
ppc_grab_regsfpdac(ppc_cur_instruction);
|
||||
|
||||
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
|
||||
ppc_confirm_inf_nan<MUL>(reg_a, reg_c, rc_flag);
|
||||
ppc_confirm_inf_nan<MUL>(reg_a, reg_c, rec);
|
||||
}
|
||||
|
||||
double ppc_dblresult64_d = (float)(val_reg_a * val_reg_c);
|
||||
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
fpresult_update(ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fmuls<RC0>();
|
||||
template void dppc_interpreter::ppc_fmuls<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fmadds() {
|
||||
ppc_grab_regsfpdabc(ppc_cur_instruction);
|
||||
|
||||
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
|
||||
ppc_confirm_inf_nan<MUL>(reg_a, reg_c, rc_flag);
|
||||
ppc_confirm_inf_nan<MUL>(reg_a, reg_c, rec);
|
||||
}
|
||||
if (std::isnan(val_reg_b)) {
|
||||
ppc_confirm_inf_nan<ADD>(reg_a, reg_b, rc_flag);
|
||||
ppc_confirm_inf_nan<ADD>(reg_a, reg_b, rec);
|
||||
}
|
||||
|
||||
double ppc_dblresult64_d = (float)std::fma(val_reg_a, val_reg_c, val_reg_b);
|
||||
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
fpresult_update(ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fmadds<RC0>();
|
||||
template void dppc_interpreter::ppc_fmadds<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fmsubs() {
|
||||
ppc_grab_regsfpdabc(ppc_cur_instruction);
|
||||
|
||||
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
|
||||
ppc_confirm_inf_nan<MUL>(reg_a, reg_c, rc_flag);
|
||||
ppc_confirm_inf_nan<MUL>(reg_a, reg_c, rec);
|
||||
}
|
||||
if (std::isnan(val_reg_b)) {
|
||||
ppc_confirm_inf_nan<SUB>(reg_a, reg_b, rc_flag);
|
||||
ppc_confirm_inf_nan<SUB>(reg_a, reg_b, rec);
|
||||
}
|
||||
|
||||
double ppc_dblresult64_d = (float)std::fma(val_reg_a, val_reg_c, -val_reg_b);
|
||||
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
fpresult_update(ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fmsubs<RC0>();
|
||||
template void dppc_interpreter::ppc_fmsubs<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fnmadds() {
|
||||
ppc_grab_regsfpdabc(ppc_cur_instruction);
|
||||
|
||||
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
|
||||
ppc_confirm_inf_nan<MUL>(reg_a, reg_c, rc_flag);
|
||||
ppc_confirm_inf_nan<MUL>(reg_a, reg_c, rec);
|
||||
}
|
||||
if (std::isnan(val_reg_b)) {
|
||||
ppc_confirm_inf_nan<ADD>(reg_a, reg_b, rc_flag);
|
||||
ppc_confirm_inf_nan<ADD>(reg_a, reg_b, rec);
|
||||
}
|
||||
|
||||
double ppc_dblresult64_d = -(float)std::fma(val_reg_a, val_reg_c, val_reg_b);
|
||||
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
fpresult_update(ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fnmadds<RC0>();
|
||||
template void dppc_interpreter::ppc_fnmadds<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fnmsubs() {
|
||||
ppc_grab_regsfpdabc(ppc_cur_instruction);
|
||||
|
||||
if (std::isnan(val_reg_a) || std::isnan(val_reg_c)) {
|
||||
ppc_confirm_inf_nan<MUL>(reg_a, reg_c, rc_flag);
|
||||
ppc_confirm_inf_nan<MUL>(reg_a, reg_c, rec);
|
||||
}
|
||||
if (std::isnan(val_reg_b)) {
|
||||
ppc_confirm_inf_nan<SUB>(reg_a, reg_b, rc_flag);
|
||||
ppc_confirm_inf_nan<SUB>(reg_a, reg_b, rec);
|
||||
}
|
||||
|
||||
double ppc_dblresult64_d = (float)std::fma(-val_reg_a, val_reg_c, val_reg_b);
|
||||
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
fpresult_update(ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fnmsubs<RC0>();
|
||||
template void dppc_interpreter::ppc_fnmsubs<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fabs() {
|
||||
ppc_grab_regsfpdb(ppc_cur_instruction);
|
||||
|
||||
@ -435,10 +500,14 @@ void dppc_interpreter::ppc_fabs() {
|
||||
|
||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fabs<RC0>();
|
||||
template void dppc_interpreter::ppc_fabs<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fnabs() {
|
||||
ppc_grab_regsfpdb(ppc_cur_instruction);
|
||||
|
||||
@ -447,10 +516,14 @@ void dppc_interpreter::ppc_fnabs() {
|
||||
|
||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fnabs<RC0>();
|
||||
template void dppc_interpreter::ppc_fnabs<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fneg() {
|
||||
ppc_grab_regsfpdb(ppc_cur_instruction);
|
||||
|
||||
@ -458,10 +531,14 @@ void dppc_interpreter::ppc_fneg() {
|
||||
|
||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fneg<RC0>();
|
||||
template void dppc_interpreter::ppc_fneg<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fsel() {
|
||||
ppc_grab_regsfpdabc(ppc_cur_instruction);
|
||||
|
||||
@ -469,54 +546,74 @@ void dppc_interpreter::ppc_fsel() {
|
||||
|
||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fsel<RC0>();
|
||||
template void dppc_interpreter::ppc_fsel<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fsqrt() {
|
||||
ppc_grab_regsfpdb(ppc_cur_instruction);
|
||||
double testd2 = (double)(GET_FPR(reg_b));
|
||||
double ppc_dblresult64_d = std::sqrt(testd2);
|
||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
ppc_confirm_inf_nan<SQRT>(0, reg_b, rc_flag);
|
||||
ppc_confirm_inf_nan<SQRT>(0, reg_b, rec);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fsqrt<RC0>();
|
||||
template void dppc_interpreter::ppc_fsqrt<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fsqrts() {
|
||||
ppc_grab_regsfpdb(ppc_cur_instruction);
|
||||
double testd2 = (double)(GET_FPR(reg_b));
|
||||
double ppc_dblresult64_d = (float)std::sqrt(testd2);
|
||||
ppc_store_sfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
ppc_confirm_inf_nan<SQRT>(0, reg_b, rc_flag);
|
||||
ppc_confirm_inf_nan<SQRT>(0, reg_b, rec);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fsqrts<RC0>();
|
||||
template void dppc_interpreter::ppc_fsqrts<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_frsqrte() {
|
||||
ppc_grab_regsfpdb(ppc_cur_instruction);
|
||||
double testd2 = (double)(GET_FPR(reg_b));
|
||||
|
||||
double ppc_dblresult64_d = 1.0 / sqrt(testd2);
|
||||
ppc_confirm_inf_nan<SQRT>(0, reg_b, rc_flag);
|
||||
ppc_confirm_inf_nan<SQRT>(0, reg_b, rec);
|
||||
|
||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_frsqrte<RC0>();
|
||||
template void dppc_interpreter::ppc_frsqrte<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_frsp() {
|
||||
ppc_grab_regsfpdb(ppc_cur_instruction);
|
||||
double ppc_dblresult64_d = (float)(GET_FPR(reg_b));
|
||||
ppc_store_dfpresult_flt(reg_d, ppc_dblresult64_d);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_frsp<RC0>();
|
||||
template void dppc_interpreter::ppc_frsp<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fres() {
|
||||
ppc_grab_regsfpdb(ppc_cur_instruction);
|
||||
double start_num = GET_FPR(reg_b);
|
||||
@ -534,11 +631,14 @@ void dppc_interpreter::ppc_fres() {
|
||||
ppc_state.fpscr |= FPSCR::VXSNAN;
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
static void round_to_int(const uint8_t mode) {
|
||||
template void dppc_interpreter::ppc_fres<RC0>();
|
||||
template void dppc_interpreter::ppc_fres<RC1>();
|
||||
|
||||
static void round_to_int(const uint8_t mode, bool rec) {
|
||||
ppc_grab_regsfpdb(ppc_cur_instruction);
|
||||
double val_reg_b = GET_FPR(reg_b);
|
||||
|
||||
@ -591,18 +691,26 @@ static void round_to_int(const uint8_t mode) {
|
||||
ppc_store_dfpresult_int(reg_d, ppc_result64_d);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fctiw() {
|
||||
round_to_int(ppc_state.fpscr & 0x3);
|
||||
round_to_int(ppc_state.fpscr & 0x3, rec);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fctiw<RC0>();
|
||||
template void dppc_interpreter::ppc_fctiw<RC1>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fctiwz() {
|
||||
round_to_int(1);
|
||||
round_to_int(1, rec);
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_fctiwz<RC0>();
|
||||
template void dppc_interpreter::ppc_fctiwz<RC1>();
|
||||
|
||||
// Floating Point Store and Load
|
||||
|
||||
void dppc_interpreter::ppc_lfs() {
|
||||
@ -769,27 +877,34 @@ void dppc_interpreter::ppc_stfiwx() {
|
||||
|
||||
// Floating Point Register Transfer
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_fmr() {
|
||||
ppc_grab_regsfpdb(ppc_cur_instruction);
|
||||
ppc_state.fpr[reg_d].dbl64_r = ppc_state.fpr[reg_b].dbl64_r;
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template <bool for601>
|
||||
template void dppc_interpreter::ppc_fmr<false>();
|
||||
template void dppc_interpreter::ppc_fmr<true>();
|
||||
|
||||
template <bool for601, bool rec>
|
||||
void dppc_interpreter::ppc_mffs() {
|
||||
ppc_grab_regsda(ppc_cur_instruction);
|
||||
int reg_d = (ppc_cur_instruction >> 21) & 31;
|
||||
|
||||
ppc_state.fpr[reg_d].int64_r = uint64_t(ppc_state.fpscr) | (for601 ? 0xFFFFFFFF00000000ULL : 0xFFF8000000000000ULL);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_mffs<false>();
|
||||
template void dppc_interpreter::ppc_mffs<true>();
|
||||
template void dppc_interpreter::ppc_mffs<false, false>();
|
||||
template void dppc_interpreter::ppc_mffs<false, true>();
|
||||
template void dppc_interpreter::ppc_mffs<true, false>();
|
||||
template void dppc_interpreter::ppc_mffs<true, true>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_mtfsf() {
|
||||
int reg_b = (ppc_cur_instruction >> 11) & 0x1F;
|
||||
uint8_t fm = (ppc_cur_instruction >> 17) & 0xFF;
|
||||
@ -815,10 +930,14 @@ void dppc_interpreter::ppc_mtfsf() {
|
||||
// copy FPR[reg_b] to FPSCR under control of cr_mask
|
||||
ppc_state.fpscr = (ppc_state.fpscr & ~cr_mask) | (ppc_state.fpr[reg_b].int64_r & cr_mask);
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_mtfsf<false>();
|
||||
template void dppc_interpreter::ppc_mtfsf<true>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_mtfsfi() {
|
||||
int crf_d = (ppc_cur_instruction >> 21) & 0x1C;
|
||||
uint32_t imm = (ppc_cur_instruction << 16) & 0xF0000000UL;
|
||||
@ -831,30 +950,41 @@ void dppc_interpreter::ppc_mtfsfi() {
|
||||
|
||||
// TODO: update FEX and VX according to the "usual rule"
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_mtfsfi<false>();
|
||||
template void dppc_interpreter::ppc_mtfsfi<true>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_mtfsb0() {
|
||||
int crf_d = (ppc_cur_instruction >> 21) & 0x1F;
|
||||
if (!crf_d || (crf_d > 2)) { // FEX and VX can't be explicitely cleared
|
||||
ppc_state.fpscr &= ~(0x80000000UL >> crf_d);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_mtfsb0<false>();
|
||||
template void dppc_interpreter::ppc_mtfsb0<true>();
|
||||
|
||||
template <bool rec>
|
||||
void dppc_interpreter::ppc_mtfsb1() {
|
||||
int crf_d = (ppc_cur_instruction >> 21) & 0x1F;
|
||||
if (!crf_d || (crf_d > 2)) { // FEX and VX can't be explicitely set
|
||||
ppc_state.fpscr |= (0x80000000UL >> crf_d);
|
||||
}
|
||||
|
||||
if (rc_flag)
|
||||
if (rec)
|
||||
ppc_update_cr1();
|
||||
}
|
||||
|
||||
template void dppc_interpreter::ppc_mtfsb1<false>();
|
||||
template void dppc_interpreter::ppc_mtfsb1<true>();
|
||||
|
||||
void dppc_interpreter::ppc_mcrfs() {
|
||||
int crf_d = (ppc_cur_instruction >> 21) & 0x1C;
|
||||
int crf_s = (ppc_cur_instruction >> 16) & 0x1C;
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user