fix for ASHC on negative value

This commit is contained in:
folkert van heusden 2022-06-09 09:46:20 +02:00
parent d243364743
commit f4b7f0a3cd

31
cpu.cpp
View file

@ -687,11 +687,12 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr)
case 3: { // ASHC
uint32_t R0R1 = (getRegister(reg) << 16) | getRegister(reg + 1);
uint16_t shift = getGAM(dst_mode, dst_reg, false, false) & 077;
bool sign = R0R1 >> 31;
bool sign = R0R1 & 0x80000000;
if (shift == 0) {
setPSW_v(false);
if (shift == 0)
setPSW_c(false);
}
else if (shift < 32) {
R0R1 <<= shift - 1;
@ -700,19 +701,27 @@ bool cpu::additional_double_operand_instructions(const uint16_t instr)
R0R1 <<= 1;
}
else {
int shift_n = (64 - shift) - 1;
// extend sign-bit
if (R0R1 & 0x80000000) // convert to unsigned 64b int & extend sign
R0R1 = (uint64_t(R0R1) | 0xffffffff00000000ll) >> (64 - (shift + 1));
else
R0R1 >>= 64 - (shift + 1);
if (sign) // convert to unsigned 64b int & extend sign
{
R0R1 = (uint64_t(R0R1) | 0xffffffff00000000ll) >> shift_n;
setPSW_c(R0R1 & 1);
setPSW_c(R0R1 & 1);
R0R1 >>= 1;
R0R1 = (uint64_t(R0R1) | 0xffffffff00000000ll) >> 1;
}
else {
R0R1 >>= shift_n;
setPSW_c(R0R1 & 1);
R0R1 >>= 1;
}
}
bool new_sign = R0R1 >> 31;
bool new_sign = R0R1 & 0x80000000;
setPSW_v(sign != new_sign);
setRegister(reg, R0R1 >> 16);