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 {
|
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!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{op}\t{Rd}, {Rs}",
|
"\t{Rd}, {Rs}",
|
||||||
op = self.alu_opcode(),
|
|
||||||
Rd = reg_string(self.rd()),
|
Rd = reg_string(self.rd()),
|
||||||
Rs = reg_string(self.rs())
|
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::bus::Bus;
|
||||||
use crate::arm7tdmi::cpu::{Core, CpuExecResult, CpuPipelineAction};
|
use crate::arm7tdmi::cpu::{Core, CpuExecResult, CpuPipelineAction};
|
||||||
use crate::arm7tdmi::*;
|
use crate::arm7tdmi::*;
|
||||||
|
@ -82,12 +82,20 @@ impl Core {
|
||||||
}
|
}
|
||||||
|
|
||||||
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 rd = insn.rd();
|
||||||
let op1 = self.get_reg(insn.rd()) as i32;
|
|
||||||
let op2 = self.get_reg(insn.rs()) as i32;
|
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);
|
let result = self.alu(arm_alu_op, op1, op2, true);
|
||||||
if let Some(result) = result {
|
if let Some(result) = result {
|
||||||
self.set_reg(insn.rd(), result as u32);
|
self.set_reg(rd, result as u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(CpuPipelineAction::IncPC)
|
Ok(CpuPipelineAction::IncPC)
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::bit::BitIndex;
|
||||||
use crate::byteorder::{LittleEndian, ReadBytesExt};
|
use crate::byteorder::{LittleEndian, ReadBytesExt};
|
||||||
use crate::num::FromPrimitive;
|
use crate::num::FromPrimitive;
|
||||||
|
|
||||||
use super::arm::{ArmCond, ArmOpCode, ArmShiftType};
|
use super::arm::*;
|
||||||
use super::{Addr, InstructionDecoder, InstructionDecoderError};
|
use super::{Addr, InstructionDecoder, InstructionDecoderError};
|
||||||
|
|
||||||
pub mod display;
|
pub mod display;
|
||||||
|
@ -241,10 +241,38 @@ impl ThumbInstruction {
|
||||||
OpFormat5::from_u8(self.raw.bit_range(8..10) as u8).unwrap()
|
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) {
|
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"),
|
0b1101 => panic!("tried to decode MUL"),
|
||||||
op => ArmOpCode::from_u16(op).unwrap(),
|
op => (ArmOpCode::from_u16(op).unwrap(), None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue