diff options
-rw-r--r-- | src/armv7.rs | 14 | ||||
-rw-r--r-- | tests/armv7/mod.rs | 3 |
2 files changed, 13 insertions, 4 deletions
diff --git a/src/armv7.rs b/src/armv7.rs index c2254a5..276b807 100644 --- a/src/armv7.rs +++ b/src/armv7.rs @@ -3815,20 +3815,26 @@ impl Decoder<ARMv7> for InstDecoder { ]; } else if op < 0b110000 { // 10xxxx - // the + 1 is to compensate for an architecturally-defined initial offset inst.opcode = Opcode::B; + + // the + 2 is to compensate for an architecturally-defined initial offset + let imm24 = ((((word & 0x00ff_ffff) + 2) << 8) as i32) >> 8; + inst.operands = [ - Operand::BranchOffset(((word & 0x00ffff) + 1) as i16 as i32), + Operand::BranchOffset(imm24), Operand::Nothing, Operand::Nothing, Operand::Nothing, ]; } else { // 11xxxx - // the + 1 is to compensate for an architecturally-defined initial offset + + // the + 2 is to compensate for an architecturally-defined initial offset + let imm24 = ((((word & 0x00ff_ffff) + 2) << 8) as i32) >> 8; + inst.opcode = Opcode::BL; inst.operands = [ - Operand::BranchOffset(((word & 0x00ffff) + 1) as i16 as i32), + Operand::BranchOffset(imm24), Operand::Nothing, Operand::Nothing, Operand::Nothing, diff --git a/tests/armv7/mod.rs b/tests/armv7/mod.rs index a60b50a..59dea7c 100644 --- a/tests/armv7/mod.rs +++ b/tests/armv7/mod.rs @@ -298,6 +298,9 @@ fn test_data_imm() { #[test] fn test_decode_misc() { + test_display([0xfe, 0xff, 0xff, 0xea], "b $+0x0"); + test_display([0xfd, 0xff, 0xff, 0xeb], "bl $-0x4"); + test_display([0x13, 0x8d, 0x04, 0xea], "b $+0x123454"); test_armv5([0x32, 0xff, 0x2f, 0xe1], "blx r2"); test_display( [0x13, 0x5f, 0x6f, 0xe1], |