mirror of
https://github.com/dingusdev/dingusppc.git
synced 2026-04-22 00:17:00 +00:00
poweropcodes: Fix mul.
Operands are supposed to be twos complement numbers. Calculate overflow first before calculating condition codes because the overflow condition is copied from XER. Fix OV calculation. Previously, it was using power_setsoov which I think is only for add and subtract operations. Fix CR calcalation. It's supposed to depend on the low order 32 bits that are placed into MQ.
This commit is contained in:
@@ -306,17 +306,19 @@ template void dppc_interpreter::power_maskir<RC1>();
|
||||
template <field_rc rec, field_ov ov>
|
||||
void dppc_interpreter::power_mul() {
|
||||
ppc_grab_regsdab(ppc_cur_instruction);
|
||||
uint64_t product;
|
||||
|
||||
product = ((uint64_t)ppc_result_a) * ((uint64_t)ppc_result_b);
|
||||
uint32_t ppc_result_d = ((uint32_t)(product >> 32));
|
||||
ppc_state.spr[SPR::MQ] = ((uint32_t)(product));
|
||||
int64_t product = int64_t(int32_t(ppc_result_a)) * int32_t(ppc_result_b);
|
||||
uint32_t ppc_result_d = uint32_t(uint64_t(product) >> 32);
|
||||
ppc_state.spr[SPR::MQ] = uint32_t(product);
|
||||
|
||||
if (ov) {
|
||||
if (uint64_t(product >> 31) + 1 & ~1) {
|
||||
ppc_state.spr[SPR::XER] |= XER::SO | XER::OV;
|
||||
} else {
|
||||
ppc_state.spr[SPR::XER] &= ~XER::OV;
|
||||
}
|
||||
}
|
||||
if (rec)
|
||||
ppc_changecrf0(ppc_result_d);
|
||||
if (ov)
|
||||
power_setsoov(ppc_result_a, ppc_result_b, ppc_result_d);
|
||||
|
||||
ppc_changecrf0(uint32_t(product));
|
||||
ppc_store_iresult_reg(reg_d, ppc_result_d);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user