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