From bb39c8a890a0650f7762cd100418d735976b5c1e Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 6 Dec 2020 11:55:59 -0800 Subject: fill out more missing thumb2 decoder --- src/armv7.rs | 6 +++++ src/armv7/thumb.rs | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/src/armv7.rs b/src/armv7.rs index 73530fb..742d1db 100644 --- a/src/armv7.rs +++ b/src/armv7.rs @@ -453,6 +453,8 @@ impl > Colorize { write!(out, "{}", colors.data_op(self)) }, @@ -663,6 +665,8 @@ impl Display for Opcode { Opcode::DBG => { write!(f, "dbg") }, Opcode::PLD => { write!(f, "pld") }, Opcode::PLI => { write!(f, "pli") }, + Opcode::RBIT => { write!(f, "rbit") }, + Opcode::SEL => { write!(f, "sel") }, } } } @@ -825,6 +829,8 @@ pub enum Opcode { DBG, PLD, PLI, + RBIT, + SEL, } static DATA_PROCESSING_OPCODES: [Opcode; 16] = [ diff --git a/src/armv7/thumb.rs b/src/armv7/thumb.rs index 6028e7b..3eac069 100644 --- a/src/armv7/thumb.rs +++ b/src/armv7/thumb.rs @@ -2882,7 +2882,71 @@ pub fn decode_into>(decoder: &InstDecoder, inst: &mut I return Err(DecodeError::Incomplete); } else if op2 < 0b1100 { // `Miscellaneous operations` (`A6-246`) - return Err(DecodeError::Incomplete); + let rn = instr2[0..4].load::(); + let rd = lower2[8..12].load::(); + let rm = lower2[0..4].load::(); + let op1 = instr2[4..6].load::(); + let op2 = lower2[4..6].load::(); + match op1 { + 0b00 => { + inst.opcode = [ + Opcode::QADD, + Opcode::QDADD, + Opcode::QSUB, + Opcode::QDSUB, + ][op2]; + inst.operands = [ + Operand::Reg(Reg::from_u8(rd)), + Operand::Reg(Reg::from_u8(rm)), + Operand::Reg(Reg::from_u8(rn)), + Operand::Nothing, + ]; + } + 0b01 => { + if rn != rm { + decoder.unpredictable()?; + } + inst.opcode = [ + Opcode::REV, + Opcode::REV16, + Opcode::RBIT, + Opcode::REVSH, + ][op2]; + inst.operands = [ + Operand::Reg(Reg::from_u8(rd)), + Operand::Reg(Reg::from_u8(rm)), + Operand::Nothing, + Operand::Nothing, + ]; + } + 0b10 => { + if op2 != 0 { + return Err(DecodeError::InvalidOpcode); + } + inst.opcode = Opcode::SEL; + inst.operands = [ + Operand::Reg(Reg::from_u8(rd)), + Operand::Reg(Reg::from_u8(rn)), + Operand::Reg(Reg::from_u8(rm)), + Operand::Nothing, + ]; + } + 0b11 => { + if op2 != 0 { + return Err(DecodeError::InvalidOpcode); + } + inst.opcode = Opcode::CLZ; + inst.operands = [ + Operand::Reg(Reg::from_u8(rd)), + Operand::Reg(Reg::from_u8(rm)), + Operand::Nothing, + Operand::Nothing, + ]; + } + _ => { + unreachable!("impossible bit pattern for op1"); + } + } } else { return Err(DecodeError::Undefined); } -- cgit v1.1