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/thumb.rs | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) (limited to 'src/armv7/thumb.rs') 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