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 {
use ArmFormat::*;
match self.fmt {
BX => self.fmt_bx(f),
B_BL => self.fmt_branch(f),
DP => self.fmt_data_processing(f),
LDR_STR => self.fmt_ldr_str(f),
LDM_STM => self.fmt_ldm_stm(f),
MRS => self.fmt_mrs(f),
MSR_REG => self.fmt_msr_reg(f),
MSR_FLAGS => self.fmt_msr_flags(f),
MUL_MLA => self.fmt_mul_mla(f),
MULL_MLAL => self.fmt_mull_mlal(f),
LDR_STR_HS_IMM => self.fmt_ldr_str_hs(f),
LDR_STR_HS_REG => self.fmt_ldr_str_hs(f),
SWI => self.fmt_swi(f),
SWP => self.fmt_swp(f),
BranchExchange => self.fmt_bx(f),
BranchLink => self.fmt_branch(f),
DataProcessing => self.fmt_data_processing(f),
SingleDataTransfer => self.fmt_ldr_str(f),
BlockDataTransfer => self.fmt_ldm_stm(f),
MoveFromStatus => self.fmt_mrs(f),
MoveToStatus => self.fmt_msr_reg(f),
MoveToFlags => self.fmt_msr_flags(f),
Multiply => self.fmt_mul_mla(f),
MultiplyLong => self.fmt_mull_mlal(f),
HalfwordDataTransferImmediateOffset => self.fmt_ldr_str_hs(f),
HalfwordDataTransferRegOffset => self.fmt_ldr_str_hs(f),
SoftwareInterrupt => self.fmt_swi(f),
SingleDataSwap => self.fmt_swp(f),
Undefined => write!(f, "<Undefined>"),
}
}

View file

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

View file

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