diff options
Diffstat (limited to 'src/armv7/thumb.rs')
| -rw-r--r-- | src/armv7/thumb.rs | 56 |
1 files changed, 48 insertions, 8 deletions
diff --git a/src/armv7/thumb.rs b/src/armv7/thumb.rs index 96b6b98..b59754c 100644 --- a/src/armv7/thumb.rs +++ b/src/armv7/thumb.rs @@ -3228,6 +3228,23 @@ pub fn decode_into<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::Word>>(d Operand::Reg(Reg::from_u8(rm)), Operand::Nothing, ]; + } else if op1 == 0b110 { + // Ra == 0b1111? unpredictable! + decoder.unpredictable()?; + if op2 >= 0b10 { + return Err(DecodeError::InvalidOpcode); + } + if op2 == 0b00 { + inst.opcode = Opcode::SMMLS; + } else { + inst.opcode = Opcode::SMMLSR; + } + inst.operands = [ + Operand::Reg(Reg::from_u8(rd)), + Operand::Reg(Reg::from_u8(rn)), + Operand::Reg(Reg::from_u8(rm)), + Operand::Reg(Reg::from_u8(ra)), + ]; } else { if op2 >= 0b10 { return Err(DecodeError::InvalidOpcode); @@ -3235,9 +3252,6 @@ pub fn decode_into<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::Word>>(d if op1 == 0b111 && op2 == 0b00 { return Err(DecodeError::InvalidOpcode); } - if op1 == 0b110 { - decoder.unpredictable()?; - } inst.opcode = [ Opcode::MUL, // already handled Opcode::UDF, // already handled @@ -3245,7 +3259,7 @@ pub fn decode_into<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::Word>>(d Opcode::UDF, // already handled Opcode::SMUSD, Opcode::SMMUL, - Opcode::SMMLS, + Opcode::SMMLS, // already handled Opcode::USAD8, ][op1]; inst.operands = [ @@ -3291,6 +3305,35 @@ pub fn decode_into<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::Word>>(d Operand::Reg(Reg::from_u8(rm)), Operand::Reg(Reg::from_u8(ra)), ]; + } else if op1 == 0b110 { + if op2 >= 0b10 { + return Err(DecodeError::InvalidOpcode); + } + if op2 == 0b00 { + inst.opcode = Opcode::SMMLS; + } else { + inst.opcode = Opcode::SMMLSR; + } + inst.operands = [ + Operand::Reg(Reg::from_u8(rd)), + Operand::Reg(Reg::from_u8(rn)), + Operand::Reg(Reg::from_u8(rm)), + Operand::Reg(Reg::from_u8(ra)), + ]; + } else if op1 == 0b101 { + if op2 == 0b00 { + inst.opcode = Opcode::SMMLA; + } else if op2 == 0b01 { + inst.opcode = Opcode::SMMLAR; + } else { + return Err(DecodeError::InvalidOpcode); + } + inst.operands = [ + Operand::Reg(Reg::from_u8(rd)), + Operand::Reg(Reg::from_u8(rn)), + Operand::Reg(Reg::from_u8(rm)), + Operand::Reg(Reg::from_u8(ra)), + ]; } else { if op2 >= 0b10 { return Err(DecodeError::InvalidOpcode); @@ -3298,9 +3341,6 @@ pub fn decode_into<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::Word>>(d if op1 == 0b111 && op2 == 0b00 { return Err(DecodeError::InvalidOpcode); } - if op1 == 0b110 { - decoder.unpredictable()?; - } inst.opcode = [ Opcode::MUL, // already handled Opcode::UDF, // already handled @@ -3308,7 +3348,7 @@ pub fn decode_into<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::Word>>(d Opcode::UDF, // already handled Opcode::SMLSD, Opcode::SMMLA, - Opcode::SMMLS, + Opcode::SMMLS, // already handled Opcode::USADA8, ][op1]; inst.operands = [ |
