Refactor ARM format names
Former-commit-id: b99e03669e2c1ccadbd13d2f06eb7127e2145f2b
This commit is contained in:
parent
a523a37d32
commit
ad232227c1
|
@ -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>"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Reference in a new issue