aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2020-12-06 15:54:48 -0800
committeriximeow <me@iximeow.net>2020-12-06 15:54:52 -0800
commit635799ae37407621f791e6fe2aa3dba141c24763 (patch)
treef4fc64b58675759b58a82d2b84667ff35cf7690b
parentc9f67f0f30cbd1459b80b2d8380fba3407e36bfa (diff)
TODONE: adr with add/subtracted offset
instead of trying to shoehorn in `adr reg, label` syntax like the manual requests, it's much easier to just describe these as `{add, sub} reg, pc, offset` and potentially rewrite `pc, offset` as an `adr reg, label` if a higher-level tool has that kind of information available.
-rw-r--r--src/armv7/thumb.rs14
-rw-r--r--test/armv7/thumb.rs8
2 files changed, 16 insertions, 6 deletions
diff --git a/src/armv7/thumb.rs b/src/armv7/thumb.rs
index 0d2a36e..3c480af 100644
--- a/src/armv7/thumb.rs
+++ b/src/armv7/thumb.rs
@@ -1281,13 +1281,14 @@ pub fn decode_into<T: IntoIterator<Item=u8>>(decoder: &InstDecoder, inst: &mut I
} else {
// `ADR` (`A8-320`)
// v6T2
- // TODO: add = TRUE;
- inst.opcode = Opcode::ADR;
+ // encoding T3
+ // handle "add = TRUE" and "add = FALSE" by calling this add/sub
+ inst.opcode = Opcode::ADD;
inst.operands = [
Operand::Reg(Reg::from_u8(rd)),
+ Operand::Reg(Reg::from_u8(15)),
Operand::Imm32(imm as u32),
Operand::Nothing,
- Operand::Nothing,
];
}
}
@@ -1318,13 +1319,14 @@ pub fn decode_into<T: IntoIterator<Item=u8>>(decoder: &InstDecoder, inst: &mut I
} else {
// `ADR` (`A8-320`)
// v6T2
- // TODO: add = FALSE;
- inst.opcode = Opcode::ADR;
+ // encoding T2
+ // handle "add = TRUE" and "add = FALSE" by calling this add/sub
+ inst.opcode = Opcode::SUB;
inst.operands = [
Operand::Reg(Reg::from_u8(rd)),
+ Operand::Reg(Reg::from_u8(15)),
Operand::Imm32(imm as u32),
Operand::Nothing,
- Operand::Nothing,
];
}
}
diff --git a/test/armv7/thumb.rs b/test/armv7/thumb.rs
index 66b5aab..b603925 100644
--- a/test/armv7/thumb.rs
+++ b/test/armv7/thumb.rs
@@ -454,6 +454,14 @@ fn test_decode_adr_cases() {
&[0xff, 0xa7],
"adr r7, 0x3fc"
);
+ test_display(
+ &[0x0f, 0xf2, 0x4f, 0x56],
+ "add r6, pc, 0x54f"
+ );
+ test_display(
+ &[0xaf, 0xf2, 0x4f, 0x56],
+ "sub r6, pc, 0x54f"
+ );
}
#[test]
fn test_decode_bcc_cases() {