Refactor ArmInstructionFormat => ArmFormat

Former-commit-id: 0ba6e1e6efedad55b2716b3f2ab5a2a629dd18a5
This commit is contained in:
Michel Heily 2019-07-01 17:51:07 +03:00
parent 6b225d776d
commit ea8c4f2a60
3 changed files with 22 additions and 22 deletions

View file

@ -1,7 +1,7 @@
use std::fmt; use std::fmt;
use super::{ use super::{
ArmCond, ArmHalfwordTransferType, ArmInstruction, ArmInstructionFormat, ArmOpCode, ArmCond, ArmHalfwordTransferType, ArmInstruction, ArmFormat, ArmOpCode,
ArmRegisterShift, ArmShiftType, ArmShiftedValue, ArmRegisterShift, ArmShiftType, ArmShiftedValue,
}; };
use crate::arm7tdmi::{reg_string, Addr, REG_PC}; use crate::arm7tdmi::{reg_string, Addr, REG_PC};
@ -367,7 +367,7 @@ impl ArmInstruction {
impl fmt::Display for ArmInstruction { impl fmt::Display for ArmInstruction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use ArmInstructionFormat::*; use ArmFormat::*;
match self.fmt { match self.fmt {
BX => self.fmt_bx(f), BX => self.fmt_bx(f),
B_BL => self.fmt_branch(f), B_BL => self.fmt_branch(f),

View file

@ -8,7 +8,7 @@ use crate::arm7tdmi::{Addr, CpuError, CpuInstruction, CpuResult, CpuState, REG_P
use crate::sysbus::SysBus; use crate::sysbus::SysBus;
use super::{ use super::{
ArmCond, ArmInstruction, ArmInstructionFormat, ArmOpCode, ArmRegisterShift, ArmShiftType, ArmCond, ArmInstruction, ArmFormat, ArmOpCode, ArmRegisterShift, ArmShiftType,
ArmShiftedValue, ArmShiftedValue,
}; };
@ -24,11 +24,11 @@ impl Core {
return Ok(CpuPipelineAction::IncPC); return Ok(CpuPipelineAction::IncPC);
} }
match insn.fmt { match insn.fmt {
ArmInstructionFormat::BX => self.exec_bx(sysbus, insn), ArmFormat::BX => self.exec_bx(sysbus, insn),
ArmInstructionFormat::B_BL => self.exec_b_bl(sysbus, insn), ArmFormat::B_BL => self.exec_b_bl(sysbus, insn),
ArmInstructionFormat::DP => self.exec_data_processing(sysbus, insn), ArmFormat::DP => self.exec_data_processing(sysbus, insn),
ArmInstructionFormat::SWI => self.exec_swi(sysbus, insn), ArmFormat::SWI => self.exec_swi(sysbus, insn),
ArmInstructionFormat::LDR_STR => self.exec_ldr_str(sysbus, insn), ArmFormat::LDR_STR => self.exec_ldr_str(sysbus, insn),
_ => Err(CpuError::UnimplementedCpuInstruction(CpuInstruction::Arm( _ => Err(CpuError::UnimplementedCpuInstruction(CpuInstruction::Arm(
insn, insn,
))), ))),

View file

@ -55,7 +55,7 @@ pub enum ArmCond {
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub enum ArmInstructionFormat { pub enum ArmFormat {
/// Branch and Exchange /// Branch and Exchange
BX, BX,
/// Branch /w Link /// Branch /w Link
@ -125,7 +125,7 @@ pub enum ArmHalfwordTransferType {
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
pub struct ArmInstruction { pub struct ArmInstruction {
pub cond: ArmCond, pub cond: ArmCond,
pub fmt: ArmInstructionFormat, pub fmt: ArmFormat,
pub raw: u32, pub raw: u32,
pub pc: Addr, pub pc: Addr,
} }
@ -134,7 +134,7 @@ impl TryFrom<(u32, Addr)> for ArmInstruction {
type Error = ArmDecodeError; type Error = ArmDecodeError;
fn try_from(value: (u32, Addr)) -> Result<Self, Self::Error> { fn try_from(value: (u32, Addr)) -> Result<Self, Self::Error> {
use ArmInstructionFormat::*; use ArmFormat::*;
let (raw, addr) = value; let (raw, addr) = value;
let cond_code = raw.bit_range(28..32) as u8; let cond_code = raw.bit_range(28..32) as u8;
@ -262,16 +262,16 @@ impl ArmInstruction {
pub fn rn(&self) -> usize { pub fn rn(&self) -> usize {
match self.fmt { match self.fmt {
ArmInstructionFormat::MUL_MLA => self.raw.bit_range(12..16) as usize, ArmFormat::MUL_MLA => self.raw.bit_range(12..16) as usize,
ArmInstructionFormat::MULL_MLAL => self.raw.bit_range(8..12) as usize, ArmFormat::MULL_MLAL => self.raw.bit_range(8..12) as usize,
ArmInstructionFormat::BX => self.raw.bit_range(0..4) as usize, ArmFormat::BX => self.raw.bit_range(0..4) as usize,
_ => self.raw.bit_range(16..20) as usize, _ => self.raw.bit_range(16..20) as usize,
} }
} }
pub fn rd(&self) -> usize { pub fn rd(&self) -> usize {
match self.fmt { match self.fmt {
ArmInstructionFormat::MUL_MLA => self.raw.bit_range(16..20) as usize, ArmFormat::MUL_MLA => self.raw.bit_range(16..20) as usize,
_ => self.raw.bit_range(12..16) as usize, _ => self.raw.bit_range(12..16) as usize,
} }
} }
@ -380,7 +380,7 @@ impl ArmInstruction {
pub fn ldr_str_hs_offset(&self) -> Result<ArmShiftedValue, ArmDecodeError> { pub fn ldr_str_hs_offset(&self) -> Result<ArmShiftedValue, ArmDecodeError> {
match self.fmt { match self.fmt {
ArmInstructionFormat::LDR_STR_HS_IMM => { ArmFormat::LDR_STR_HS_IMM => {
let offset8 = (self.raw.bit_range(8..12) << 4) + self.raw.bit_range(0..4); let offset8 = (self.raw.bit_range(8..12) << 4) + self.raw.bit_range(0..4);
let offset8 = if self.add_offset_flag() { let offset8 = if self.add_offset_flag() {
offset8 as i32 offset8 as i32
@ -389,7 +389,7 @@ impl ArmInstruction {
}; };
Ok(ArmShiftedValue::ImmediateValue(offset8)) Ok(ArmShiftedValue::ImmediateValue(offset8))
} }
ArmInstructionFormat::LDR_STR_HS_REG => Ok(ArmShiftedValue::ShiftedRegister { ArmFormat::LDR_STR_HS_REG => Ok(ArmShiftedValue::ShiftedRegister {
reg: (self.raw & 0xf) as usize, reg: (self.raw & 0xf) as usize,
shift: ArmRegisterShift::ShiftAmount(0, ArmShiftType::LSL), shift: ArmRegisterShift::ShiftAmount(0, ArmShiftType::LSL),
added: Some(self.add_offset_flag()), added: Some(self.add_offset_flag()),
@ -441,7 +441,7 @@ mod tests {
fn test_decode_swi() { fn test_decode_swi() {
// swi #0x1337 // swi #0x1337
let decoded = ArmInstruction::try_from(0xef001337).unwrap(); let decoded = ArmInstruction::try_from(0xef001337).unwrap();
assert_eq!(decoded.fmt, ArmInstructionFormat::SWI); assert_eq!(decoded.fmt, ArmFormat::SWI);
assert_eq!(decoded.swi_comment(), 0x1337); assert_eq!(decoded.swi_comment(), 0x1337);
assert_eq!(format!("{}", decoded), "swi\t#0x1337"); assert_eq!(format!("{}", decoded), "swi\t#0x1337");
} }
@ -450,7 +450,7 @@ mod tests {
fn test_decode_branch_forwards() { fn test_decode_branch_forwards() {
// 0x20: b 0x30 // 0x20: b 0x30
let decoded = ArmInstruction::try_from((0xea_00_00_02, 0x20)).unwrap(); let decoded = ArmInstruction::try_from((0xea_00_00_02, 0x20)).unwrap();
assert_eq!(decoded.fmt, ArmInstructionFormat::B_BL); assert_eq!(decoded.fmt, ArmFormat::B_BL);
assert_eq!(decoded.link_flag(), false); assert_eq!(decoded.link_flag(), false);
assert_eq!( assert_eq!(
(decoded.pc as i32).wrapping_add(decoded.branch_offset()) + 8, (decoded.pc as i32).wrapping_add(decoded.branch_offset()) + 8,
@ -463,7 +463,7 @@ mod tests {
fn test_decode_branch_link_backwards() { fn test_decode_branch_link_backwards() {
// 0x20: bl 0x10 // 0x20: bl 0x10
let decoded = ArmInstruction::try_from((0xeb_ff_ff_fa, 0x20)).unwrap(); let decoded = ArmInstruction::try_from((0xeb_ff_ff_fa, 0x20)).unwrap();
assert_eq!(decoded.fmt, ArmInstructionFormat::B_BL); assert_eq!(decoded.fmt, ArmFormat::B_BL);
assert_eq!(decoded.link_flag(), true); assert_eq!(decoded.link_flag(), true);
assert_eq!( assert_eq!(
(decoded.pc as i32).wrapping_add(decoded.branch_offset()) + 8, (decoded.pc as i32).wrapping_add(decoded.branch_offset()) + 8,
@ -476,7 +476,7 @@ mod tests {
fn test_decode_ldr_preindex() { fn test_decode_ldr_preindex() {
// ldreq r2, [r5, -r6, lsl #5] // ldreq r2, [r5, -r6, lsl #5]
let decoded = ArmInstruction::try_from(0x07_15_22_86).unwrap(); let decoded = ArmInstruction::try_from(0x07_15_22_86).unwrap();
assert_eq!(decoded.fmt, ArmInstructionFormat::LDR_STR); assert_eq!(decoded.fmt, ArmFormat::LDR_STR);
assert_eq!(decoded.cond, ArmCond::Equal); assert_eq!(decoded.cond, ArmCond::Equal);
assert_eq!(decoded.load_flag(), true); assert_eq!(decoded.load_flag(), true);
assert_eq!(decoded.pre_index_flag(), true); assert_eq!(decoded.pre_index_flag(), true);
@ -499,7 +499,7 @@ mod tests {
fn test_decode_str_postindex() { fn test_decode_str_postindex() {
// strteq r2, [r4], -r7, lsl #8 // strteq r2, [r4], -r7, lsl #8
let decoded = ArmInstruction::try_from(0x06_24_24_47).unwrap(); let decoded = ArmInstruction::try_from(0x06_24_24_47).unwrap();
assert_eq!(decoded.fmt, ArmInstructionFormat::LDR_STR); assert_eq!(decoded.fmt, ArmFormat::LDR_STR);
assert_eq!(decoded.cond, ArmCond::Equal); assert_eq!(decoded.cond, ArmCond::Equal);
assert_eq!(decoded.load_flag(), false); assert_eq!(decoded.load_flag(), false);
assert_eq!(decoded.pre_index_flag(), false); assert_eq!(decoded.pre_index_flag(), false);