aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG1
-rw-r--r--src/armv7/thumb.rs6
-rw-r--r--tests/armv7/thumb.rs13
3 files changed, 18 insertions, 2 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 60dd00d..15a9c15 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -35,6 +35,7 @@
* thumb2: fix ssat and ssat16's second operand being decoded off-by-one.
the field is 1-based rather than 0-based, so for example an instruction which
had that operand as "1" was incorrectly decoded as being "0"
+* thumb2: fix `hvc` immediate missing its upper four bits
* ARMv7: do not try to elide memory offset when 0 in postindex operands.
this makes a post-index (and implied writeback!) ambiguous with a pre-indexed
access with offset zero. that is, `[r1, 0]` may be written as `[r1]`, but
diff --git a/src/armv7/thumb.rs b/src/armv7/thumb.rs
index dacf3dd..96b6b98 100644
--- a/src/armv7/thumb.rs
+++ b/src/armv7/thumb.rs
@@ -2091,9 +2091,11 @@ pub fn decode_into<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::Word>>(d
// `HVC` (`B8-1970`)
// v7VE
let imm = lower & 0b1111_1111_1111;
+ let imm_upper = instr & 0b1111;
+ let imm = (imm_upper << 12) | imm;
inst.opcode = Opcode::HVC;
inst.operands = [
- Operand::Imm12(imm),
+ Operand::Imm32(imm as u32),
Operand::Nothing,
Operand::Nothing,
Operand::Nothing,
@@ -2818,7 +2820,7 @@ pub fn decode_into<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::Word>>(d
// TODO: so, this is gross! the PLD/PLI/PLT handling needs improvement across
// the board.
- if inst.opcode == Opcode::PLD {
+ if inst.opcode == Opcode::PLD || inst.opcode == Opcode::PLI {
inst.operands[0] = inst.operands[1];
inst.operands[1] = Operand::Nothing;
}
diff --git a/tests/armv7/thumb.rs b/tests/armv7/thumb.rs
index 00b5802..6b8c891 100644
--- a/tests/armv7/thumb.rs
+++ b/tests/armv7/thumb.rs
@@ -4746,6 +4746,19 @@ fn prefetch() {
&[0x10, 0xf8, 0x7c, 0xfe],
"ldrbt.w pc, [r0, #0x7c]"
);
+
+ test_display(
+ &[0x93, 0xf9, 0x00, 0xf6],
+ "pli.w [r3, #0x6000x78]"
+ );
+}
+
+#[test]
+fn hvc() {
+ test_display(
+ &[0xe2, 0xf7, 0x00, 0x81],
+ "hvc.w #0x2100"
+ );
}
#[test]