diff --git a/bindings/rustboyadvance-jni/Cargo.toml b/bindings/rustboyadvance-jni/Cargo.toml index 8b8ca71..33aba92 100644 --- a/bindings/rustboyadvance-jni/Cargo.toml +++ b/bindings/rustboyadvance-jni/Cargo.toml @@ -10,7 +10,7 @@ publish = false crate-type = ["staticlib", "cdylib"] [dependencies] -rustboyadvance-core = {path = "../../core/", features = ["arm7tdmi_dispatch_table", "no_video_interface"]} +rustboyadvance-core = {path = "../../core/", features = ["no_video_interface"]} jni = "0.17.0" log = {version = "0.4.8", features = ["release_max_level_info", "max_level_debug"]} diff --git a/core/Cargo.toml b/core/Cargo.toml index f094821..2c23504 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -57,12 +57,9 @@ name = "performance" harness = false [features] -default = ["arm7tdmi_dispatch_table"] +default = [] elf_support = ["goblin"] debugger = ["nom", "rustyline", "fuzzy-matcher", "elf_support"] gdb = ["gdbstub"] -# Uses lookup tables when executing instructions instead of `match` statements. -# Faster, but consumes more memory. -arm7tdmi_dispatch_table = [] # For use for ports where VideoInterface is not needed like wasm & jni no_video_interface = [] diff --git a/core/build.rs b/core/build.rs index 21757a4..3deefd8 100644 --- a/core/build.rs +++ b/core/build.rs @@ -420,20 +420,15 @@ fn generate_arm_lut(file: &mut fs::File) -> Result<(), std::io::Error> { } fn main() { - let arm7tdmi_dispatch_table_enabled = - env::var_os("CARGO_FEATURE_ARM7TDMI_DISPATCH_TABLE").is_some(); + // TODO - don't do this in the build script and use `const fn` instead when it becomes stable + let out_dir = env::var_os("OUT_DIR").unwrap(); + let thumb_lut_path = Path::new(&out_dir).join("thumb_lut.rs"); + let mut thumb_lut_file = fs::File::create(&thumb_lut_path).expect("failed to create file"); + generate_thumb_lut(&mut thumb_lut_file).expect("failed to generate thumb table"); - if arm7tdmi_dispatch_table_enabled { - // TODO - don't do this in the build script and use `const fn` instead when it becomes stable - let out_dir = env::var_os("OUT_DIR").unwrap(); - let thumb_lut_path = Path::new(&out_dir).join("thumb_lut.rs"); - let mut thumb_lut_file = fs::File::create(&thumb_lut_path).expect("failed to create file"); - generate_thumb_lut(&mut thumb_lut_file).expect("failed to generate thumb table"); + let arm_lut_path = Path::new(&out_dir).join("arm_lut.rs"); + let mut arm_lut_file = fs::File::create(&arm_lut_path).expect("failed to create file"); + generate_arm_lut(&mut arm_lut_file).expect("failed to generate arm table"); - let arm_lut_path = Path::new(&out_dir).join("arm_lut.rs"); - let mut arm_lut_file = fs::File::create(&arm_lut_path).expect("failed to create file"); - generate_arm_lut(&mut arm_lut_file).expect("failed to generate arm table"); - - println!("cargo:rerun-if-changed=build.rs"); - } + println!("cargo:rerun-if-changed=build.rs"); } diff --git a/core/src/arm7tdmi/arm/exec.rs b/core/src/arm7tdmi/arm/exec.rs index f835a43..ed74e47 100644 --- a/core/src/arm7tdmi/arm/exec.rs +++ b/core/src/arm7tdmi/arm/exec.rs @@ -12,27 +12,6 @@ use super::ArmDecodeHelper; use super::*; impl Core { - #[cfg(not(feature = "arm7tdmi_dispatch_table"))] - pub fn exec_arm(&mut self, insn: u32, fmt: ArmFormat) -> CpuAction { - match fmt { - ArmFormat::BranchExchange => self.exec_arm_bx(insn), - ArmFormat::BranchLink => self.exec_arm_b_bl(insn), - ArmFormat::DataProcessing => self.exec_arm_data_processing(insn), - ArmFormat::SoftwareInterrupt => self.exec_arm_swi(insn), - ArmFormat::SingleDataTransfer => self.exec_arm_ldr_str(insn), - ArmFormat::HalfwordDataTransferImmediateOffset => self.exec_arm_ldr_str_hs_imm(insn), - ArmFormat::HalfwordDataTransferRegOffset => self.exec_arm_ldr_str_hs_reg(insn), - ArmFormat::BlockDataTransfer => self.exec_arm_ldm_stm(insn), - ArmFormat::MoveFromStatus => self.exec_arm_mrs(insn), - ArmFormat::MoveToStatus => self.exec_arm_transfer_to_status(insn), - ArmFormat::MoveToFlags => self.exec_arm_transfer_to_status(insn), - ArmFormat::Multiply => self.exec_arm_mul_mla(insn), - ArmFormat::MultiplyLong => self.exec_arm_mull_mlal(insn), - ArmFormat::SingleDataSwap => self.exec_arm_swp(insn), - ArmFormat::Undefined => self.arm_undefined(insn), - } - } - pub fn arm_undefined(&mut self, insn: u32) -> CpuAction { panic!( "executing undefined arm instruction {:08x} at @{:08x}", diff --git a/core/src/arm7tdmi/cpu.rs b/core/src/arm7tdmi/cpu.rs index 0d95bcb..8c8bcb3 100644 --- a/core/src/arm7tdmi/cpu.rs +++ b/core/src/arm7tdmi/cpu.rs @@ -11,32 +11,24 @@ use MemoryAccess::*; use cfg_if::cfg_if; -cfg_if! { - if #[cfg(feature = "arm7tdmi_dispatch_table")] { +#[cfg(feature = "debugger")] +use super::thumb::ThumbFormat; - #[cfg(feature = "debugger")] - use super::thumb::ThumbFormat; +#[cfg(feature = "debugger")] +use super::arm::ArmFormat; - #[cfg(feature = "debugger")] - use super::arm::ArmFormat; +#[cfg_attr(not(feature = "debugger"), repr(transparent))] +pub struct ThumbInstructionInfo { + pub handler_fn: fn(&mut Core, insn: u16) -> CpuAction, + #[cfg(feature = "debugger")] + pub fmt: ThumbFormat, +} - #[cfg_attr(not(feature = "debugger"), repr(transparent))] - pub struct ThumbInstructionInfo { - pub handler_fn: fn(&mut Core, insn: u16) -> CpuAction, - #[cfg(feature = "debugger")] - pub fmt: ThumbFormat, - } - - #[cfg_attr(not(feature = "debugger"), repr(transparent))] - pub struct ArmInstructionInfo { - pub handler_fn: fn(&mut Core, insn: u32) -> CpuAction, - #[cfg(feature = "debugger")] - pub fmt: ArmFormat, - } - } else { - use super::arm::ArmFormat; - use super::thumb::ThumbFormat; - } +#[cfg_attr(not(feature = "debugger"), repr(transparent))] +pub struct ArmInstructionInfo { + pub handler_fn: fn(&mut Core, insn: u32) -> CpuAction, + #[cfg(feature = "debugger")] + pub fmt: ArmFormat, } cfg_if! { @@ -364,53 +356,27 @@ impl Core { self.dbg.last_executed = Some(d); } - cfg_if! { - if #[cfg(feature = "arm7tdmi_dispatch_table")] { - fn step_arm_exec(&mut self, insn: u32) -> CpuAction { - let hash = (((insn >> 16) & 0xff0) | ((insn >> 4) & 0xf)) as usize; - let arm_info = &Self::ARM_LUT[hash]; - #[cfg(feature = "debugger")] - self.debugger_record_step(DecodedInstruction::Arm(ArmInstruction::new( - insn, - self.pc.wrapping_sub(8), - arm_info.fmt, - ))); - (arm_info.handler_fn)(self, insn) - } + fn step_arm_exec(&mut self, insn: u32) -> CpuAction { + let hash = (((insn >> 16) & 0xff0) | ((insn >> 4) & 0xf)) as usize; + let arm_info = &Self::ARM_LUT[hash]; + #[cfg(feature = "debugger")] + self.debugger_record_step(DecodedInstruction::Arm(ArmInstruction::new( + insn, + self.pc.wrapping_sub(8), + arm_info.fmt, + ))); + (arm_info.handler_fn)(self, insn) + } - fn step_thumb_exec(&mut self, insn: u16) -> CpuAction { - let thumb_info = &Self::THUMB_LUT[(insn >> 6) as usize]; - #[cfg(feature = "debugger")] - self.debugger_record_step(DecodedInstruction::Thumb(ThumbInstruction::new( - insn, - self.pc.wrapping_sub(4), - thumb_info.fmt, - ))); - (thumb_info.handler_fn)(self, insn) - } - } else { - - fn step_arm_exec(&mut self, insn: u32) -> CpuAction { - let arm_fmt = ArmFormat::from(insn); - #[cfg(feature = "debugger")] - self.debugger_record_step(DecodedInstruction::Arm(ArmInstruction::new( - insn, - self.pc.wrapping_sub(8), - arm_fmt, - ))); - self.exec_arm(insn, arm_fmt) - } - fn step_thumb_exec(&mut self, insn: u16) -> CpuAction { - let thumb_fmt = ThumbFormat::from(insn); - #[cfg(feature = "debugger")] - self.debugger_record_step(DecodedInstruction::Thumb(ThumbInstruction::new( - insn, - self.pc.wrapping_sub(4), - thumb_fmt, - ))); - self.exec_thumb(insn, thumb_fmt) - } - } + fn step_thumb_exec(&mut self, insn: u16) -> CpuAction { + let thumb_info = &Self::THUMB_LUT[(insn >> 6) as usize]; + #[cfg(feature = "debugger")] + self.debugger_record_step(DecodedInstruction::Thumb(ThumbInstruction::new( + insn, + self.pc.wrapping_sub(4), + thumb_info.fmt, + ))); + (thumb_info.handler_fn)(self, insn) } /// 2S + 1N @@ -558,7 +524,5 @@ impl fmt::Display for Core { } } -#[cfg(feature = "arm7tdmi_dispatch_table")] include!(concat!(env!("OUT_DIR"), "/arm_lut.rs")); -#[cfg(feature = "arm7tdmi_dispatch_table")] include!(concat!(env!("OUT_DIR"), "/thumb_lut.rs")); diff --git a/core/src/arm7tdmi/thumb/exec.rs b/core/src/arm7tdmi/thumb/exec.rs index a2e11f6..d36f90a 100644 --- a/core/src/arm7tdmi/thumb/exec.rs +++ b/core/src/arm7tdmi/thumb/exec.rs @@ -575,30 +575,4 @@ impl Core { self.pc_thumb() ) } - - #[cfg(not(feature = "arm7tdmi_dispatch_table"))] - pub fn exec_thumb(&mut self, insn: u16, fmt: ThumbFormat) -> CpuAction { - match fmt { - ThumbFormat::MoveShiftedReg => self.exec_thumb_move_shifted_reg(insn), - ThumbFormat::AddSub => self.exec_thumb_add_sub(insn), - ThumbFormat::DataProcessImm => self.exec_thumb_data_process_imm(insn), - ThumbFormat::AluOps => self.exec_thumb_alu_ops(insn), - ThumbFormat::HiRegOpOrBranchExchange => self.exec_thumb_hi_reg_op_or_bx(insn), - ThumbFormat::LdrPc => self.exec_thumb_ldr_pc(insn), - ThumbFormat::LdrStrRegOffset => self.exec_thumb_ldr_str_reg_offset(insn), - ThumbFormat::LdrStrSHB => self.exec_thumb_ldr_str_shb(insn), - ThumbFormat::LdrStrImmOffset => self.exec_thumb_ldr_str_imm_offset(insn), - ThumbFormat::LdrStrHalfWord => self.exec_thumb_ldr_str_halfword(insn), - ThumbFormat::LdrStrSp => self.exec_thumb_ldr_str_sp(insn), - ThumbFormat::LoadAddress => self.exec_thumb_load_address(insn), - ThumbFormat::AddSp => self.exec_thumb_add_sp(insn), - ThumbFormat::PushPop => self.exec_thumb_push_pop(insn), - ThumbFormat::LdmStm => self.exec_thumb_ldm_stm(insn), - ThumbFormat::BranchConditional => self.exec_thumb_branch_with_cond(insn), - ThumbFormat::Swi => self.exec_thumb_swi(insn), - ThumbFormat::Branch => self.exec_thumb_branch(insn), - ThumbFormat::BranchLongWithLink => self.exec_thumb_branch_long_with_link(insn), - ThumbFormat::Undefined => self.thumb_undefined(insn), - } - } } diff --git a/platform/rustboyadvance-sdl2/Cargo.toml b/platform/rustboyadvance-sdl2/Cargo.toml index 4abd808..fe106e2 100644 --- a/platform/rustboyadvance-sdl2/Cargo.toml +++ b/platform/rustboyadvance-sdl2/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Michel Heily "] edition = "2018" [dependencies] -rustboyadvance-core = { path = "../../core/", features = ["elf_support", "arm7tdmi_dispatch_table"] } +rustboyadvance-core = { path = "../../core/", features = ["elf_support"] } sdl2 = { version = "0.33.0", features = ["image"] } ringbuf = "0.2.2" bytesize = "1.0.0"