diff options
Diffstat (limited to 'src/state/shifter_value.rs')
-rw-r--r-- | src/state/shifter_value.rs | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/src/state/shifter_value.rs b/src/state/shifter_value.rs new file mode 100644 index 0000000..58821fe --- /dev/null +++ b/src/state/shifter_value.rs @@ -0,0 +1,130 @@ +/* + Copyright 2021-2023 Gabriel Jensen. + + This file is part of Luma. + + Luma is free software: you can redistribute it + and/or modify it under the terms of the GNU + Affero General Public License as published by + the Free Software Foundation, either version 3 + of the License, or (at your option) any later + version. + + Luma is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU + Affero General Public License along with Luma. + If not, see <https://www.gnu.org/licenses/>. +*/ + +use crate::shifter::Shifter; +use crate::state::State; + +impl State { + #[must_use] + pub fn shifter_value(&self, shifter: Shifter) -> (u32, bool) { + use Shifter::*; + + let c = self.read_cpsr() & 0b00100000000000000000000000000000 != 0x0; + + let (value, carry) = match shifter { + Immediate(imm, rot) => { + let result = (imm as u32).rotate_right(rot as u32); + let c = if rot == 0x0 { c } else { result & 0b10000000000000000000000000000000 != 0x0 }; + + (result, c) + }, + + ArithmeticShiftRightImmediate(rm, imm) => { + let rm_value = self.read_register(rm); + + let result = (rm_value as i32).wrapping_shr(imm as u32) as u32; + let c = false; // TODO + + (result, c) + }, + + ArithmeticShiftRightRegister(rm, rs) => { + let rm_value = self.read_register(rm); + let rs_value = self.read_register(rs); + + let result = (rm_value as i32).wrapping_shr(rs_value) as u32; + let c = false; // TODO + + (result, c) + }, + + LogicalShiftLeftImmediate(rm, imm) => { + let rm_value = self.read_register(rm); + + let result = rm_value.wrapping_shl(imm as u32); + let c = false; // TODO + + (result, c) + }, + + LogicalShiftLeftRegister(rm, rs) => { + let rm_value = self.read_register(rm); + let rs_value = self.read_register(rs); + + let result = rm_value.wrapping_shl(rs_value); + let c = false; // TODO + + (result, c) + }, + + LogicalShiftRightImmediate(rm, imm) => { + let rm_value = self.read_register(rm); + + let result = rm_value.wrapping_shr(imm as u32); + let c = false; // TODO + + (result, c) + }, + + LogicalShiftRightRegister(rm, rs) => { + let rm_value = self.read_register(rm); + let rs_value = self.read_register(rs); + + let result = rm_value.wrapping_shr(rs_value); + let c = false; // TODO + + (result, c) + }, + + RotateRightImmediate(rm, imm) => { + let rm_value = self.read_register(rm); + + let result = rm_value.rotate_right(imm as u32); + let c = false; // TODO + + (result, c) + }, + + RotateRightRegister(rm, rs) => { + let rm_value = self.read_register(rm); + let rs_value = self.read_register(rs); + + let result = rm_value.rotate_right(rs_value); + let c = false; // TODO + + (result, c) + }, + + RotateRightExtend(rm) => { + let rm_value = self.read_register(rm); + + let result = 0x0_u32; // TODO + let c = rm_value & 0b00000000000000000000000000000001 != 0x0; + + (result, c) + }, + }; + + return (value, carry); + } +} |