Refactor ARM format names

Former-commit-id: b99e03669e2c1ccadbd13d2f06eb7127e2145f2b
This commit is contained in:
Michel Heily 2020-04-05 20:19:18 +03:00
parent a523a37d32
commit ad232227c1
3 changed files with 76 additions and 86 deletions

View file

@ -416,20 +416,20 @@ impl fmt::Display for ArmInstruction {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use ArmFormat::*; use ArmFormat::*;
match self.fmt { match self.fmt {
BX => self.fmt_bx(f), BranchExchange => self.fmt_bx(f),
B_BL => self.fmt_branch(f), BranchLink => self.fmt_branch(f),
DP => self.fmt_data_processing(f), DataProcessing => self.fmt_data_processing(f),
LDR_STR => self.fmt_ldr_str(f), SingleDataTransfer => self.fmt_ldr_str(f),
LDM_STM => self.fmt_ldm_stm(f), BlockDataTransfer => self.fmt_ldm_stm(f),
MRS => self.fmt_mrs(f), MoveFromStatus => self.fmt_mrs(f),
MSR_REG => self.fmt_msr_reg(f), MoveToStatus => self.fmt_msr_reg(f),
MSR_FLAGS => self.fmt_msr_flags(f), MoveToFlags => self.fmt_msr_flags(f),
MUL_MLA => self.fmt_mul_mla(f), Multiply => self.fmt_mul_mla(f),
MULL_MLAL => self.fmt_mull_mlal(f), MultiplyLong => self.fmt_mull_mlal(f),
LDR_STR_HS_IMM => self.fmt_ldr_str_hs(f), HalfwordDataTransferImmediateOffset => self.fmt_ldr_str_hs(f),
LDR_STR_HS_REG => self.fmt_ldr_str_hs(f), HalfwordDataTransferRegOffset => self.fmt_ldr_str_hs(f),
SWI => self.fmt_swi(f), SoftwareInterrupt => self.fmt_swi(f),
SWP => self.fmt_swp(f), SingleDataSwap => self.fmt_swp(f),
Undefined => write!(f, "<Undefined>"), Undefined => write!(f, "<Undefined>"),
} }
} }

View file

@ -12,21 +12,21 @@ use super::*;
impl Core { impl Core {
pub fn exec_arm(&mut self, bus: &mut SysBus, insn: &ArmInstruction) -> CpuAction { pub fn exec_arm(&mut self, bus: &mut SysBus, insn: &ArmInstruction) -> CpuAction {
match insn.fmt { match insn.fmt {
ArmFormat::BX => self.exec_arm_bx(bus, insn), ArmFormat::BranchExchange => self.exec_arm_bx(bus, insn),
ArmFormat::B_BL => self.exec_arm_b_bl(bus, insn), ArmFormat::BranchLink => self.exec_arm_b_bl(bus, insn),
ArmFormat::DP => self.exec_arm_data_processing(bus, insn), ArmFormat::DataProcessing => self.exec_arm_data_processing(bus, insn),
ArmFormat::SWI => self.exec_arm_swi(bus, insn), ArmFormat::SoftwareInterrupt => self.exec_arm_swi(bus, insn),
ArmFormat::LDR_STR => self.exec_arm_ldr_str(bus, insn), ArmFormat::SingleDataTransfer => self.exec_arm_ldr_str(bus, insn),
ArmFormat::LDR_STR_HS_IMM => self.exec_arm_ldr_str_hs(bus, insn), ArmFormat::HalfwordDataTransferImmediateOffset => self.exec_arm_ldr_str_hs(bus, insn),
ArmFormat::LDR_STR_HS_REG => self.exec_arm_ldr_str_hs(bus, insn), ArmFormat::HalfwordDataTransferRegOffset => self.exec_arm_ldr_str_hs(bus, insn),
ArmFormat::LDM_STM => self.exec_arm_ldm_stm(bus, insn), ArmFormat::BlockDataTransfer => self.exec_arm_ldm_stm(bus, insn),
ArmFormat::MRS => self.exec_arm_mrs(bus, insn), ArmFormat::MoveFromStatus => self.exec_arm_mrs(bus, insn),
ArmFormat::MSR_REG => self.exec_arm_msr_reg(bus, insn), ArmFormat::MoveToStatus => self.exec_arm_msr_reg(bus, insn),
ArmFormat::MSR_FLAGS => self.exec_arm_msr_flags(bus, insn), ArmFormat::MoveToFlags => self.exec_arm_msr_flags(bus, insn),
ArmFormat::MUL_MLA => self.exec_arm_mul_mla(bus, insn), ArmFormat::Multiply => self.exec_arm_mul_mla(bus, insn),
ArmFormat::MULL_MLAL => self.exec_arm_mull_mlal(bus, insn), ArmFormat::MultiplyLong => self.exec_arm_mull_mlal(bus, insn),
ArmFormat::SWP => self.exec_arm_swp(bus, insn), ArmFormat::SingleDataSwap => self.exec_arm_swp(bus, insn),
ArmFormat::Undefined => panic!("Undefined instruction "), ArmFormat::Undefined => self.arm_undefined(bus, insn),
} }
} }

View file

@ -65,36 +65,24 @@ pub enum ArmCond {
} }
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq)] #[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq)]
#[allow(non_camel_case_types)]
pub enum ArmFormat { pub enum ArmFormat {
/// Branch and Exchange BranchExchange = 0,
BX, BranchLink,
/// Branch /w Link SoftwareInterrupt,
B_BL, Multiply,
/// Software interrupt MultiplyLong,
SWI, SingleDataTransfer,
// Multiply and Multiply-Accumulate HalfwordDataTransferRegOffset,
MUL_MLA, HalfwordDataTransferImmediateOffset,
/// Multiply Long and Multiply-Accumulate Long DataProcessing,
MULL_MLAL, BlockDataTransfer,
/// Single Data Transfer SingleDataSwap,
LDR_STR,
/// Halfword and Signed Data Transfer
LDR_STR_HS_REG,
/// Halfword and Signed Data Transfer
LDR_STR_HS_IMM,
/// Data Processing
DP,
/// Block Data Transfer
LDM_STM,
/// Single Data Swap
SWP,
/// Transfer PSR contents to a register /// Transfer PSR contents to a register
MRS, MoveFromStatus,
/// Transfer register contents to PSR /// Transfer register contents to PSR
MSR_REG, MoveToStatus,
/// Tanssfer immediate/register to PSR flags only /// Tanssfer immediate/register to PSR flags only
MSR_FLAGS, MoveToFlags,
Undefined, Undefined,
} }
@ -126,35 +114,35 @@ impl InstructionDecoder for ArmInstruction {
use ArmFormat::*; use ArmFormat::*;
let fmt = if (0x0fff_fff0 & raw) == 0x012f_ff10 { let fmt = if (0x0fff_fff0 & raw) == 0x012f_ff10 {
BX BranchExchange
} else if (0x0e00_0000 & raw) == 0x0a00_0000 { } else if (0x0e00_0000 & raw) == 0x0a00_0000 {
B_BL BranchLink
} else if (0xe000_0010 & raw) == 0x0600_0000 { } else if (0xe000_0010 & raw) == 0x0600_0000 {
Undefined Undefined
} else if (0x0fb0_0ff0 & raw) == 0x0100_0090 { } else if (0x0fb0_0ff0 & raw) == 0x0100_0090 {
SWP SingleDataSwap
} else if (0x0fc0_00f0 & raw) == 0x0000_0090 { } else if (0x0fc0_00f0 & raw) == 0x0000_0090 {
MUL_MLA Multiply
} else if (0x0f80_00f0 & raw) == 0x0080_0090 { } else if (0x0f80_00f0 & raw) == 0x0080_0090 {
MULL_MLAL MultiplyLong
} else if (0x0fbf_0fff & raw) == 0x010f_0000 { } else if (0x0fbf_0fff & raw) == 0x010f_0000 {
MRS MoveFromStatus
} else if (0x0fbf_fff0 & raw) == 0x0129_f000 { } else if (0x0fbf_fff0 & raw) == 0x0129_f000 {
MSR_REG MoveToStatus
} else if (0x0dbf_f000 & raw) == 0x0128_f000 { } else if (0x0dbf_f000 & raw) == 0x0128_f000 {
MSR_FLAGS MoveToFlags
} else if (0x0c00_0000 & raw) == 0x0400_0000 { } else if (0x0c00_0000 & raw) == 0x0400_0000 {
LDR_STR SingleDataTransfer
} else if (0x0e40_0F90 & raw) == 0x0000_0090 { } else if (0x0e40_0F90 & raw) == 0x0000_0090 {
LDR_STR_HS_REG HalfwordDataTransferRegOffset
} else if (0x0e40_0090 & raw) == 0x0040_0090 { } else if (0x0e40_0090 & raw) == 0x0040_0090 {
LDR_STR_HS_IMM HalfwordDataTransferImmediateOffset
} else if (0x0e00_0000 & raw) == 0x0800_0000 { } else if (0x0e00_0000 & raw) == 0x0800_0000 {
LDM_STM BlockDataTransfer
} else if (0x0f00_0000 & raw) == 0x0f00_0000 { } else if (0x0f00_0000 & raw) == 0x0f00_0000 {
SWI SoftwareInterrupt
} else if (0x0c00_0000 & raw) == 0x0000_0000 { } else if (0x0c00_0000 & raw) == 0x0000_0000 {
DP DataProcessing
} else { } else {
Undefined Undefined
}; };
@ -192,16 +180,16 @@ impl ArmInstruction {
pub fn rn(&self) -> usize { pub fn rn(&self) -> usize {
match self.fmt { match self.fmt {
ArmFormat::MUL_MLA => self.raw.bit_range(12..16) as usize, ArmFormat::Multiply => self.raw.bit_range(12..16) as usize,
ArmFormat::MULL_MLAL => self.raw.bit_range(8..12) as usize, ArmFormat::MultiplyLong => self.raw.bit_range(8..12) as usize,
ArmFormat::BX => self.raw.bit_range(0..4) as usize, ArmFormat::BranchExchange => 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 {
ArmFormat::MUL_MLA => self.raw.bit_range(16..20) as usize, ArmFormat::Multiply => self.raw.bit_range(16..20) as usize,
_ => self.raw.bit_range(12..16) as usize, _ => self.raw.bit_range(12..16) as usize,
} }
} }
@ -323,7 +311,7 @@ impl ArmInstruction {
pub fn ldr_str_hs_offset(&self) -> Result<BarrelShifterValue, ArmDecodeError> { pub fn ldr_str_hs_offset(&self) -> Result<BarrelShifterValue, ArmDecodeError> {
match self.fmt { match self.fmt {
ArmFormat::LDR_STR_HS_IMM => { ArmFormat::HalfwordDataTransferImmediateOffset => {
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 offset8
@ -332,12 +320,14 @@ impl ArmInstruction {
}; };
Ok(BarrelShifterValue::ImmediateValue(offset8)) Ok(BarrelShifterValue::ImmediateValue(offset8))
} }
ArmFormat::LDR_STR_HS_REG => Ok(BarrelShifterValue::ShiftedRegister(ShiftedRegister { ArmFormat::HalfwordDataTransferRegOffset => {
reg: (self.raw & 0xf) as usize, Ok(BarrelShifterValue::ShiftedRegister(ShiftedRegister {
shift_by: ShiftRegisterBy::ByAmount(0), reg: (self.raw & 0xf) as usize,
bs_op: BarrelShiftOpCode::LSL, shift_by: ShiftRegisterBy::ByAmount(0),
added: Some(self.add_offset_flag()), bs_op: BarrelShiftOpCode::LSL,
})), added: Some(self.add_offset_flag()),
}))
}
_ => Err(self.make_decode_error(DecodedPartDoesNotBelongToInstruction)), _ => Err(self.make_decode_error(DecodedPartDoesNotBelongToInstruction)),
} }
} }
@ -385,7 +375,7 @@ impl ArmInstruction {
// // swi #0x1337 // // swi #0x1337
// let decoded = ArmInstruction::decode(0xef001337, 0).unwrap(); // let decoded = ArmInstruction::decode(0xef001337, 0).unwrap();
// assert_eq!(decoded.fmt, ArmFormat::SWI); // assert_eq!(decoded.fmt, ArmFormat::SoftwareInterrupt);
// 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");
@ -400,7 +390,7 @@ impl ArmInstruction {
// fn branch_forwards() { // fn branch_forwards() {
// // 0x20: b 0x30 // // 0x20: b 0x30
// let decoded = ArmInstruction::decode(0xea_00_00_02, 0x20).unwrap(); // let decoded = ArmInstruction::decode(0xea_00_00_02, 0x20).unwrap();
// assert_eq!(decoded.fmt, ArmFormat::B_BL); // assert_eq!(decoded.fmt, ArmFormat::BranchLink);
// 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,
@ -423,7 +413,7 @@ impl ArmInstruction {
// fn branch_link_backwards() { // fn branch_link_backwards() {
// // 0x20: bl 0x10 // // 0x20: bl 0x10
// let decoded = ArmInstruction::decode(0xeb_ff_ff_fa, 0x20).unwrap(); // let decoded = ArmInstruction::decode(0xeb_ff_ff_fa, 0x20).unwrap();
// assert_eq!(decoded.fmt, ArmFormat::B_BL); // assert_eq!(decoded.fmt, ArmFormat::BranchLink);
// 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,
@ -446,7 +436,7 @@ impl ArmInstruction {
// fn ldr_pre_index() { // fn ldr_pre_index() {
// // ldreq r2, [r5, -r6, lsl #5] // // ldreq r2, [r5, -r6, lsl #5]
// let decoded = ArmInstruction::decode(0x07_15_22_86, 0).unwrap(); // let decoded = ArmInstruction::decode(0x07_15_22_86, 0).unwrap();
// assert_eq!(decoded.fmt, ArmFormat::LDR_STR); // assert_eq!(decoded.fmt, ArmFormat::SingleDataTransfer);
// assert_eq!(decoded.cond, ArmCond::EQ); // assert_eq!(decoded.cond, ArmCond::EQ);
// 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);
@ -488,7 +478,7 @@ impl ArmInstruction {
// fn str_post_index() { // fn str_post_index() {
// // strteq r2, [r4], -r7, asr #8 // // strteq r2, [r4], -r7, asr #8
// let decoded = ArmInstruction::decode(0x06_24_24_47, 0).unwrap(); // let decoded = ArmInstruction::decode(0x06_24_24_47, 0).unwrap();
// assert_eq!(decoded.fmt, ArmFormat::LDR_STR); // assert_eq!(decoded.fmt, ArmFormat::SingleDataTransfer);
// assert_eq!(decoded.cond, ArmCond::EQ); // assert_eq!(decoded.cond, ArmCond::EQ);
// 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);
@ -529,7 +519,7 @@ impl ArmInstruction {
// fn str_pre_index() { // fn str_pre_index() {
// // str r4, [sp, 0x10] // // str r4, [sp, 0x10]
// let decoded = ArmInstruction::decode(0xe58d4010, 0).unwrap(); // let decoded = ArmInstruction::decode(0xe58d4010, 0).unwrap();
// assert_eq!(decoded.fmt, ArmFormat::LDR_STR); // assert_eq!(decoded.fmt, ArmFormat::SingleDataTransfer);
// assert_eq!(decoded.cond, ArmCond::AL); // assert_eq!(decoded.cond, ArmCond::AL);
// let mut core = Core::new(); // let mut core = Core::new();