/* 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 . */ use crate::shifter::Shifter; use std::hint::unreachable_unchecked; impl Shifter { pub fn extract(opcode: u32) -> Self { use Shifter::*; match opcode & 0b00000010000000000000000000000000 != 0x0 { false => { let rm = (opcode & 0b00000000000000000000000000001111) as u8; let shift = (opcode & 0b00000000000000000000000001100000).wrapping_shr(0x5) as u8; let register_shift = opcode & 0b00000000000000000000000000010000 != 0x0; match register_shift { false => { let imm = (opcode & 0b00000000000000000000111110000000).wrapping_shr(0x7) as u8; return match shift { 0b11 => match imm { 0x0 => RotateRightExtend( rm), imm => RotateRightImmediate(rm, imm), }, shift => { match shift { 0b00 => LogicalShiftLeftImmediate(rm, imm), 0b01 => LogicalShiftRightImmediate(rm, match imm { 0x0 => 0x20, imm => imm, }), 0b10 => ArithmeticShiftRightImmediate(rm, match imm { 0x0 => 0x20, imm => imm, }), _ => unsafe { unreachable_unchecked() }, } }, }; }, true => { let rs = (opcode & 0b0000000000000000000111100000000).wrapping_shr(0x8) as u8; return match shift { 0b00 => LogicalShiftLeftRegister( rm, rs), 0b01 => LogicalShiftRightRegister( rm, rs), 0b10 => ArithmeticShiftRightRegister(rm, rs), 0b11 => RotateRightRegister( rm, rs), _ => unsafe { unreachable_unchecked() }, }; }, }; }, true => { let imm = (opcode & 0b00000000000000000000000011111111) as u8; let rot = (opcode & 0b00000000000000000000111100000000).wrapping_shr(0x7) as u8; return Immediate(imm, rot); }, }; } }