aboutsummaryrefslogtreecommitdiff
path: root/src/armv7/thumb.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/armv7/thumb.rs')
-rw-r--r--src/armv7/thumb.rs56
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 = [