Impl Thumb 19, fix warnings and rustfmt

Former-commit-id: 8690aa25b1aa343b344776716b6213596bd1459a
This commit is contained in:
Michel Heily 2019-07-05 15:34:52 +03:00
parent fb0d3acb14
commit d4b6952411
9 changed files with 68 additions and 43 deletions

View file

@ -1,6 +1,6 @@
use crate::bit::BitIndex;
use crate::arm7tdmi::bus::{Bus, MemoryAccessType::*, MemoryAccessWidth::*};
use crate::arm7tdmi::bus::Bus;
use crate::arm7tdmi::cpu::{Core, CpuExecResult, CpuPipelineAction};
use crate::arm7tdmi::exception::Exception;
use crate::arm7tdmi::psr::RegPSR;
@ -31,7 +31,7 @@ impl Core {
}
/// Cycles 2S+1N
fn exec_b_bl(&mut self, bus: &mut Bus, insn: ArmInstruction) -> CpuResult<CpuPipelineAction> {
fn exec_b_bl(&mut self, _bus: &mut Bus, insn: ArmInstruction) -> CpuResult<CpuPipelineAction> {
if insn.link_flag() {
self.set_reg(14, (insn.pc + (self.word_size() as u32)) & !0b1);
}
@ -42,7 +42,7 @@ impl Core {
}
/// Cycles 2S+1N
fn exec_bx(&mut self, bus: &mut Bus, insn: ArmInstruction) -> CpuResult<CpuPipelineAction> {
fn exec_bx(&mut self, _bus: &mut Bus, insn: ArmInstruction) -> CpuResult<CpuPipelineAction> {
let rn = self.get_reg(insn.rn());
if rn.bit(0) {
self.cpsr.set_state(CpuState::THUMB);
@ -62,7 +62,7 @@ impl Core {
fn exec_msr_reg(
&mut self,
bus: &mut Bus,
_bus: &mut Bus,
insn: ArmInstruction,
) -> CpuResult<CpuPipelineAction> {
let new_psr = RegPSR::new(self.get_reg(insn.rm()));
@ -119,6 +119,7 @@ impl Core {
res
}
#[allow(non_snake_case)]
pub fn alu(
&mut self,
opcode: ArmOpCode,
@ -129,7 +130,7 @@ impl Core {
let C = self.cpsr.C() as i32;
let mut carry = self.cpsr.C();
let mut overflow = self.cpsr.V();
let overflow = self.cpsr.V();
let result = match opcode {
ArmOpCode::AND | ArmOpCode::TST => op1 & op2,
@ -165,7 +166,7 @@ impl Core {
/// Add x=1I cycles if Op2 shifted-by-register. Add y=1S+1N cycles if Rd=R15.
fn exec_data_processing(
&mut self,
bus: &mut Bus,
_bus: &mut Bus,
insn: ArmInstruction,
) -> CpuResult<CpuPipelineAction> {
// TODO handle carry flag
@ -251,7 +252,6 @@ impl Core {
if insn.rn() == REG_PC {
addr = insn.pc + 8; // prefetching
}
let dest = self.get_reg(insn.rd());
let offset = self.get_rn_offset(&insn);

View file

@ -198,12 +198,6 @@ impl fmt::Display for CpuError {
pub type CpuResult<T> = Result<T, CpuError>;
pub struct CpuModeContext {
// r8-r14
banked_gpr: [u32; 7],
spsr: u32,
}
#[cfg(test)]
mod tests {
#[test]

View file

@ -3,7 +3,7 @@ use std::fmt;
use crate::bit::BitIndex;
use super::*;
use crate::arm7tdmi::reg_string;
use crate::arm7tdmi::*;
impl ThumbInstruction {
fn fmt_thumb_move_shifted_reg(&self, f: &mut fmt::Formatter) -> fmt::Result {
@ -158,6 +158,17 @@ impl ThumbInstruction {
}
)
}
fn fmt_thumb_branch_long_with_link(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "bl\t#0x{:08x}", {
let offset11 = self.offset11();
if self.flag(ThumbInstruction::FLAG_LOW_OFFSET) {
(offset11 << 1) as i32
} else {
((offset11 << 21) >> 9) as i32
}
})
}
}
impl fmt::Display for ThumbInstruction {
@ -175,6 +186,7 @@ impl fmt::Display for ThumbInstruction {
ThumbFormat::AddSp => self.fmt_thumb_add_sp(f),
ThumbFormat::PushPop => self.fmt_thumb_push_pop(f),
ThumbFormat::BranchConditional => self.fmt_thumb_branch_with_cond(f),
ThumbFormat::BranchLongWithLink => self.fmt_thumb_branch_long_with_link(f),
_ => write!(f, "({:?})", self),
}
}

View file

@ -1,7 +1,7 @@
use crate::arm7tdmi::arm::*;
use crate::arm7tdmi::bus::{Bus, MemoryAccessType::*, MemoryAccessWidth::*};
use crate::arm7tdmi::bus::Bus;
use crate::arm7tdmi::cpu::{Core, CpuExecResult, CpuPipelineAction};
use crate::arm7tdmi::{reg_string, Addr, CpuState, REG_LR, REG_PC, REG_SP};
use crate::arm7tdmi::*;
use super::*;
fn push(cpu: &mut Core, bus: &mut Bus, r: usize) {
@ -19,7 +19,7 @@ fn pop(cpu: &mut Core, bus: &mut Bus, r: usize) {
impl Core {
fn exec_thumb_move_shifted_reg(
&mut self,
bus: &mut Bus,
_bus: &mut Bus,
insn: ThumbInstruction,
) -> CpuExecResult {
let result = self
@ -33,7 +33,7 @@ impl Core {
Ok(CpuPipelineAction::IncPC)
}
fn exec_thumb_add_sub(&mut self, bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult {
fn exec_thumb_add_sub(&mut self, _bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult {
let op1 = self.get_reg(insn.rs()) as i32;
let op2 = if insn.is_immediate_operand() {
insn.rn() as u32 as i32
@ -56,7 +56,7 @@ impl Core {
fn exec_thumb_data_process_imm(
&mut self,
bus: &mut Bus,
_bus: &mut Bus,
insn: ThumbInstruction,
) -> CpuExecResult {
let arm_alu_op: ArmOpCode = insn.format3_op().into();
@ -70,18 +70,18 @@ impl Core {
Ok(CpuPipelineAction::IncPC)
}
fn exec_thumb_mul(&mut self, bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult {
fn exec_thumb_mul(&mut self, _bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult {
let op1 = self.get_reg(insn.rd()) as i32;
let op2 = self.get_reg(insn.rs()) as i32;
let m = self.get_required_multipiler_array_cycles(op2);
for i in 0..m {
for _ in 0..m {
self.add_cycle();
}
self.gpr[insn.rd()] = (op1 * op2) as u32;
Ok(CpuPipelineAction::IncPC)
}
fn exec_thumb_alu_ops(&mut self, bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult {
fn exec_thumb_alu_ops(&mut self, _bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult {
let arm_alu_op: ArmOpCode = insn.alu_opcode();
let op1 = self.get_reg(insn.rd()) as i32;
let op2 = self.get_reg(insn.rs()) as i32;
@ -94,7 +94,7 @@ impl Core {
}
/// Cycles 2S+1N
fn exec_thumb_bx(&mut self, bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult {
fn exec_thumb_bx(&mut self, _bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult {
let src_reg = if insn.flag(ThumbInstruction::FLAG_H2) {
insn.rs() + 8
} else {
@ -180,7 +180,7 @@ impl Core {
Ok(CpuPipelineAction::IncPC)
}
fn exec_thumb_add_sp(&mut self, bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult {
fn exec_thumb_add_sp(&mut self, _bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult {
let op1 = self.gpr[REG_SP] as i32;
let op2 = insn.sword7();
let arm_alu_op = ArmOpCode::ADD;
@ -230,12 +230,33 @@ impl Core {
if !self.check_arm_cond(insn.cond()) {
Ok(CpuPipelineAction::IncPC)
} else {
let offset = insn.offset8() as u8 as i32;
let offset = insn.offset8() as i8 as i32;
self.pc = (insn.pc as i32).wrapping_add(offset) as u32;
Ok(CpuPipelineAction::Flush)
}
}
fn exec_thumb_branch_long_with_link(
&mut self,
_bus: &mut Bus,
insn: ThumbInstruction,
) -> CpuExecResult {
let mut off = insn.offset11();
if insn.flag(ThumbInstruction::FLAG_LOW_OFFSET) {
off = off << 1;
let next_pc = (self.pc - 2) | 1;
self.pc = (self.gpr[REG_LR] as i32).wrapping_add(off) as u32;
self.gpr[REG_LR] = next_pc;
Ok(CpuPipelineAction::Flush)
} else {
off = (off << 21) >> 9;
self.gpr[REG_LR] = (self.pc as i32).wrapping_add(off) as u32;
Ok(CpuPipelineAction::IncPC)
}
}
pub fn exec_thumb(&mut self, bus: &mut Bus, insn: ThumbInstruction) -> CpuExecResult {
match insn.fmt {
ThumbFormat::MoveShiftedReg => self.exec_thumb_move_shifted_reg(bus, insn),
@ -250,6 +271,7 @@ impl Core {
ThumbFormat::AddSp => self.exec_thumb_add_sp(bus, insn),
ThumbFormat::PushPop => self.exec_thumb_push_pop(bus, insn),
ThumbFormat::BranchConditional => self.exec_thumb_branch_with_cond(bus, insn),
ThumbFormat::BranchLongWithLink => self.exec_thumb_branch_long_with_link(bus, insn),
_ => unimplemented!("thumb not implemented {:#x?}", insn),
}
}

View file

@ -198,6 +198,7 @@ impl ThumbInstruction {
const FLAG_H2: usize = 6;
const FLAG_R: usize = 8;
const FLAG_S: usize = 7;
const FLAG_LOW_OFFSET: usize = 11;
pub fn rd(&self) -> usize {
match self.fmt {
@ -252,6 +253,10 @@ impl ThumbInstruction {
self.raw.bit_range(0..8) as i8
}
pub fn offset11(&self) -> i32 {
(self.raw & 0x7FF) as i32
}
pub fn word8(&self) -> u16 {
self.raw.bit_range(0..8) << 2
}

View file

@ -1,9 +1,7 @@
use std::str::from_utf8;
use nom::number::streaming::le_u32;
use crate::arm7tdmi::{
bus::{Bus, MemoryAccess, MemoryAccessType, MemoryAccessWidth},
bus::{Bus, MemoryAccess, MemoryAccessWidth},
Addr,
};
use crate::sysbus::WaitState;

View file

@ -1,7 +1,3 @@
use std::fmt;
use crate::arm7tdmi::Addr;
use nom;
use nom::branch::alt;
use nom::bytes::complete::{tag, take_while1, take_while_m_n};

View file

@ -1,8 +1,6 @@
use std::convert::TryFrom;
use std::marker::PhantomData;
use super::arm7tdmi::{Addr, InstructionDecoder, InstructionDecoderError};
use std::io;
use std::io::ErrorKind;
pub struct Disassembler<'a, D>

View file

@ -69,38 +69,38 @@ impl Bus for BoxedMemory {
struct DummyBus([u8; 4]);
impl Bus for DummyBus {
fn read_32(&self, addr: Addr) -> u32 {
fn read_32(&self, _addr: Addr) -> u32 {
0
}
fn read_16(&self, addr: Addr) -> u16 {
fn read_16(&self, _addr: Addr) -> u16 {
0
}
fn read_8(&self, addr: Addr) -> u8 {
fn read_8(&self, _addr: Addr) -> u8 {
0
}
fn write_32(&mut self, addr: Addr, value: u32) -> Result<(), io::Error> {
fn write_32(&mut self, _addr: Addr, _value: u32) -> Result<(), io::Error> {
Ok(())
}
fn write_16(&mut self, addr: Addr, value: u16) -> Result<(), io::Error> {
fn write_16(&mut self, _addr: Addr, _value: u16) -> Result<(), io::Error> {
Ok(())
}
fn write_8(&mut self, addr: Addr, value: u8) -> Result<(), io::Error> {
fn write_8(&mut self, _addr: Addr, _value: u8) -> Result<(), io::Error> {
Ok(())
}
fn get_bytes(&self, addr: Addr) -> &[u8] {
fn get_bytes(&self, _addr: Addr) -> &[u8] {
&self.0
}
fn get_bytes_mut(&mut self, addr: Addr) -> &mut [u8] {
fn get_bytes_mut(&mut self, _addr: Addr) -> &mut [u8] {
&mut self.0
}
fn get_cycles(&self, addr: Addr, access: MemoryAccess) -> usize {
fn get_cycles(&self, _addr: Addr, _access: MemoryAccess) -> usize {
1
}
}