thumb: Fix ALU ops for barrel shifter opcodes
I kinda missed these when I read the manual >< Former-commit-id: 7d6c21b6c3b46bf065a177c1c7f7a7a1baa6b8fa
This commit is contained in:
parent
163d8bda59
commit
ecdd6e0ed4
|
@ -37,10 +37,15 @@ impl ThumbInstruction {
|
|||
}
|
||||
|
||||
fn fmt_thumb_alu_ops(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let (op, shft) = self.alu_opcode();
|
||||
if let Some(ArmRegisterShift::ShiftRegister(_, shftOp)) = shft {
|
||||
write!(f, "{}", shftOp)?;
|
||||
} else {
|
||||
write!(f, "{}", op)?;
|
||||
}
|
||||
write!(
|
||||
f,
|
||||
"{op}\t{Rd}, {Rs}",
|
||||
op = self.alu_opcode(),
|
||||
"\t{Rd}, {Rs}",
|
||||
Rd = reg_string(self.rd()),
|
||||
Rs = reg_string(self.rs())
|
||||
)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::arm7tdmi::arm::*;
|
||||
use crate::arm7tdmi::arm::exec::*;
|
||||
use crate::arm7tdmi::bus::Bus;
|
||||
use crate::arm7tdmi::cpu::{Core, CpuExecResult, CpuPipelineAction};
|
||||
use crate::arm7tdmi::*;
|
||||
|
@ -82,12 +82,20 @@ impl Core {
|
|||
}
|
||||
|
||||
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;
|
||||
let rd = insn.rd();
|
||||
|
||||
let (arm_alu_op, shft) = insn.alu_opcode();
|
||||
let op1 = self.get_reg(rd) as i32;
|
||||
let op2 = if let Some(shft) = shft {
|
||||
let bs_result = self.register_shift(rd, shft)?;
|
||||
bs_result
|
||||
} else {
|
||||
self.get_reg(insn.rs()) as i32
|
||||
};
|
||||
|
||||
let result = self.alu(arm_alu_op, op1, op2, true);
|
||||
if let Some(result) = result {
|
||||
self.set_reg(insn.rd(), result as u32);
|
||||
self.set_reg(rd, result as u32);
|
||||
}
|
||||
|
||||
Ok(CpuPipelineAction::IncPC)
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::bit::BitIndex;
|
|||
use crate::byteorder::{LittleEndian, ReadBytesExt};
|
||||
use crate::num::FromPrimitive;
|
||||
|
||||
use super::arm::{ArmCond, ArmOpCode, ArmShiftType};
|
||||
use super::arm::*;
|
||||
use super::{Addr, InstructionDecoder, InstructionDecoderError};
|
||||
|
||||
pub mod display;
|
||||
|
@ -241,10 +241,38 @@ impl ThumbInstruction {
|
|||
OpFormat5::from_u8(self.raw.bit_range(8..10) as u8).unwrap()
|
||||
}
|
||||
|
||||
pub fn alu_opcode(&self) -> ArmOpCode {
|
||||
pub fn alu_opcode(&self) -> (ArmOpCode, Option<ArmRegisterShift>) {
|
||||
match self.raw.bit_range(6..10) {
|
||||
0b0010 => (
|
||||
ArmOpCode::MOV,
|
||||
Some(ArmRegisterShift::ShiftRegister(
|
||||
self.rs(),
|
||||
ArmShiftType::LSL,
|
||||
)),
|
||||
),
|
||||
0b0011 => (
|
||||
ArmOpCode::MOV,
|
||||
Some(ArmRegisterShift::ShiftRegister(
|
||||
self.rs(),
|
||||
ArmShiftType::LSR,
|
||||
)),
|
||||
),
|
||||
0b0100 => (
|
||||
ArmOpCode::MOV,
|
||||
Some(ArmRegisterShift::ShiftRegister(
|
||||
self.rs(),
|
||||
ArmShiftType::ASR,
|
||||
)),
|
||||
),
|
||||
0b0111 => (
|
||||
ArmOpCode::MOV,
|
||||
Some(ArmRegisterShift::ShiftRegister(
|
||||
self.rs(),
|
||||
ArmShiftType::ROR,
|
||||
)),
|
||||
),
|
||||
0b1101 => panic!("tried to decode MUL"),
|
||||
op => ArmOpCode::from_u16(op).unwrap(),
|
||||
op => (ArmOpCode::from_u16(op).unwrap(), None),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Reference in a new issue