mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-12-25 18:29:49 +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:
parent
ef8522e101
commit
1e57ac408a
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user