Fix carry flag on barrel shifter ops

Former-commit-id: 31cf2166d97fcdcca0dd9c59591f5e28b5b5f6cc
This commit is contained in:
Michel Heily 2019-07-05 18:31:08 +03:00
parent 638e449421
commit 4da863da9b

View file

@ -82,12 +82,42 @@ impl Core {
Ok(CpuPipelineAction::IncPC) Ok(CpuPipelineAction::IncPC)
} }
fn barrel_shift(val: i32, amount: u32, shift: ArmShiftType) -> i32 { fn barrel_shift(&mut self, val: i32, amount: u32, shift: ArmShiftType) -> i32 {
match shift { match shift {
ArmShiftType::LSL => val.wrapping_shl(amount), ArmShiftType::LSL => {
ArmShiftType::LSR => (val as u32).wrapping_shr(amount) as i32, if amount < 32 {
ArmShiftType::ASR => val.wrapping_shr(amount), self.cpsr.set_C(val.wrapping_shr(32 - amount) & 1 == 1);
ArmShiftType::ROR => val.rotate_right(amount), } else {
if amount == 32 {
self.cpsr.set_C(val & 1 == 1);
} else {
self.cpsr.set_C(false)
}
}
val.wrapping_shl(amount)
}
ArmShiftType::LSR => {
if amount < 32 {
self.cpsr.set_C(val.wrapping_shr(amount - 1) & 1 == 1);
} else {
self.cpsr.set_C(false);
}
(val as u32).wrapping_shr(amount) as i32
}
ArmShiftType::ASR => {
if amount < 32 {
self.cpsr.set_C(val.wrapping_shr(amount - 1) & 1 == 1);
} else {
self.cpsr.set_C(val >> 31 == 1);
}
val.wrapping_shr(amount)
}
ArmShiftType::ROR => {
let amount = amount % 32;
let result = val.rotate_right(amount);
self.cpsr.set_C((result >> 1) &1 == 1);
result
}
} }
} }
@ -95,11 +125,11 @@ impl Core {
let val = self.get_reg(reg) as i32; let val = self.get_reg(reg) as i32;
match shift { match shift {
ArmRegisterShift::ShiftAmount(amount, shift) => { ArmRegisterShift::ShiftAmount(amount, shift) => {
Ok(Core::barrel_shift(val, amount, shift)) Ok(self.barrel_shift(val, amount, shift))
} }
ArmRegisterShift::ShiftRegister(reg, shift) => { ArmRegisterShift::ShiftRegister(reg, shift) => {
if reg != REG_PC { if reg != REG_PC {
Ok(Core::barrel_shift(val, self.get_reg(reg) & 0xff, shift)) Ok(self.barrel_shift(val, self.get_reg(reg) & 0xff, shift))
} else { } else {
Err(CpuError::IllegalInstruction) Err(CpuError::IllegalInstruction)
} }