Skip to content

Commit

Permalink
Merge pull request #49 from jjkt/sbfx
Browse files Browse the repository at this point in the history
SBFX support
  • Loading branch information
jjkt authored Dec 1, 2024
2 parents 2ca5e75 + 9e8a7d5 commit 1528d08
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 15 deletions.
1 change: 1 addition & 0 deletions zmu_cortex_m/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ fn main() -> Result<(), Box<dyn Error>> {
("111101111111....1010............", "UDF_t2"),
("11110011111011111000............", "MRS_t1"),
("111100111100....0.........0.....", "UBFX_t1"),
("111100110100....0.........0.....", "SBFX_t1"),
("1111001110111111100011110110....", "ISB_t1"),
("1111001110111111100011110101....", "DMB_t1"),
("1111001110111111100011110100....", "DSB_t1"),
Expand Down
17 changes: 14 additions & 3 deletions zmu_cortex_m/src/core/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ pub struct Reg2RtRnImm32Params {

#[allow(missing_docs)]
#[derive(PartialEq, Debug, Copy, Clone)]
pub struct UbfxParams {
pub struct BfxParams {
pub rd: Reg,
pub rn: Reg,
pub lsb: usize,
Expand Down Expand Up @@ -976,9 +976,12 @@ pub enum Instruction {
},

//SBFX - signed bit field extract
SBFX {
params: BfxParams,
},
/// Unsigned bit field extract
UBFX {
params: UbfxParams,
params: BfxParams,
},

// --------------------------------------------
Expand Down Expand Up @@ -2305,6 +2308,14 @@ impl fmt::Display for Instruction {
params.lsb,
params.widthminus1 + 1
),
Self::SBFX { params } => write!(
f,
"sbfx {}, {}, #{}, #{}",
params.rd,
params.rn,
params.lsb,
params.widthminus1 + 1
),
Self::VLDR { params } => write!(f, "vldr {}, {}", params.dd, params.rn),
Self::VSTR { params } => write!(f, "vstr {}, {}", params.dd, params.rn),
Self::VSTM_T1 { params } => write!(
Expand Down Expand Up @@ -2589,7 +2600,7 @@ pub fn instruction_size(instruction: &Instruction) -> usize {
//SASX
Instruction::SBC_imm { .. } => 4,
Instruction::SBC_reg { thumb32, .. } => isize_t(*thumb32),
//SBFX
Instruction::SBFX { .. } => 4,
Instruction::SDIV { .. } => 4,
Instruction::SEL { .. } => 4,
Instruction::SEV { thumb32, .. } => isize_t(*thumb32),
Expand Down
20 changes: 18 additions & 2 deletions zmu_cortex_m/src/decoder/decoder_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::core::instruction::{
Reg2ShiftNoSetFlagsParams, Reg2ShiftParams, Reg2UsizeParams, Reg3FullParams, Reg3HighParams,
Reg3NoSetFlagsParams, Reg3Params, Reg3RdRtRnImm32Params, Reg3ShiftParams, Reg3UsizeParams,
Reg4HighParams, Reg4NoSetFlagsParams, Reg643232Params, RegImm32AddParams,
RegImmCarryNoSetFlagsParams, RegImmCarryParams, RegImmParams, SRType, SetFlags, UbfxParams,
RegImmCarryNoSetFlagsParams, RegImmCarryParams, RegImmParams, SRType, SetFlags, BfxParams,
VMovCr2DpParams, VMovCrSpParams, VMovImmParams64, VMovRegParamsf32,
};

Expand Down Expand Up @@ -1448,7 +1448,7 @@ fn test_decode_ubfx() {
assert_eq!(
decode_32(0xf3c0_0140),
Instruction::UBFX {
params: UbfxParams {
params: BfxParams {
rd: Reg::R1,
rn: Reg::R0,
lsb: 1,
Expand All @@ -1458,6 +1458,22 @@ fn test_decode_ubfx() {
);
}

#[test]
fn test_decode_sbfx() {
// SBFX r3, r3, #0, #1
assert_eq!(
decode_32(0xf343_0300),
Instruction::SBFX {
params: BfxParams {
rd: Reg::R3,
rn: Reg::R3,
lsb: 0,
widthminus1: 0,
}
}
);
}

#[test]
fn test_decode_udiv() {
// UDIV R0, R0, R1
Expand Down
14 changes: 9 additions & 5 deletions zmu_cortex_m/src/decoder/sbfx.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use crate::core::instruction::Instruction;
use crate::core::bits::Bits;
use crate::core::instruction::{Instruction, BfxParams};

#[allow(non_snake_case)]
pub fn decode_SBFX_t1(opcode: u32) -> Instruction {
Instruction::UDF {
imm32: 0,
opcode: opcode.into(),
thumb32: true,
Instruction::SBFX {
params: BfxParams {
rd: From::from(opcode.get_bits(8..12) as u8),
rn: From::from(opcode.get_bits(16..20) as u8),
lsb: (opcode.get_bits(6..8) + (opcode.get_bits(12..15) << 2)) as usize,
widthminus1: opcode.get_bits(0..5) as usize,
},
}
}
4 changes: 2 additions & 2 deletions zmu_cortex_m/src/decoder/ubfx.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::core::bits::Bits;
use crate::core::instruction::{Instruction, UbfxParams};
use crate::core::instruction::{Instruction, BfxParams};

#[allow(non_snake_case)]
pub fn decode_UBFX_t1(opcode: u32) -> Instruction {
Instruction::UBFX {
params: UbfxParams {
params: BfxParams {
rd: From::from(opcode.get_bits(8..12) as u8),
rn: From::from(opcode.get_bits(16..20) as u8),
lsb: (opcode.get_bits(6..8) + (opcode.get_bits(12..15) << 2)) as usize,
Expand Down
24 changes: 21 additions & 3 deletions zmu_cortex_m/src/executor/misc_data_processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use super::ExecuteResult;
use crate::core::{
bits::Bits,
instruction::{
BfcParams, BfiParams, MovtParams, Reg2RdRmParams, Reg3NoSetFlagsParams, UbfxParams,
BfcParams, BfiParams, MovtParams, Reg2RdRmParams, Reg3NoSetFlagsParams, BfxParams,
},
operation::sign_extend,
register::{Apsr, BaseReg},
Expand All @@ -25,7 +25,8 @@ pub trait IsaMiscDataProcessing {
fn exec_rev16(&mut self, params: Reg2RdRmParams) -> ExecuteResult;
fn exec_revsh(&mut self, params: Reg2RdRmParams) -> ExecuteResult;
fn exec_sel(&mut self, params: &Reg3NoSetFlagsParams) -> ExecuteResult;
fn exec_ubfx(&mut self, params: &UbfxParams) -> ExecuteResult;
fn exec_ubfx(&mut self, params: &BfxParams) -> ExecuteResult;
fn exec_sbfx(&mut self, params: &BfxParams) -> ExecuteResult;
}

impl IsaMiscDataProcessing for Processor {
Expand Down Expand Up @@ -170,7 +171,7 @@ impl IsaMiscDataProcessing for Processor {
Ok(ExecuteSuccess::NotTaken)
}

fn exec_ubfx(&mut self, params: &UbfxParams) -> ExecuteResult {
fn exec_ubfx(&mut self, params: &BfxParams) -> ExecuteResult {
if self.condition_passed() {
let msbit = params.lsb + params.widthminus1;
if msbit <= 31 {
Expand All @@ -185,6 +186,23 @@ impl IsaMiscDataProcessing for Processor {
}
Ok(ExecuteSuccess::NotTaken)
}

fn exec_sbfx(&mut self, params: &BfxParams) -> ExecuteResult {
if self.condition_passed() {
let msbit = params.lsb + params.widthminus1;
if msbit <= 31 {
let upper = msbit + 1;
let data = self.get_r(params.rn).get_bits(params.lsb..upper);
let data = sign_extend(data, msbit, 32) as i32;
self.set_r(params.rd, data as u32);
} else {
todo!();
}

return Ok(ExecuteSuccess::Taken { cycles: 1 });
}
Ok(ExecuteSuccess::NotTaken)
}
}

#[cfg(test)]
Expand Down
1 change: 1 addition & 0 deletions zmu_cortex_m/src/executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ impl ExecutorHelper for Processor {
Instruction::REVSH { params, .. } => self.exec_revsh(*params),

Instruction::UBFX { params } => self.exec_ubfx(params),
Instruction::SBFX { params } => self.exec_sbfx(params),

// --------------------------------------------
//
Expand Down

0 comments on commit 1528d08

Please sign in to comment.