From 9570dae514462f4a823e54de11e6dc86587de1b7 Mon Sep 17 00:00:00 2001 From: Mitchell Johnson Date: Sun, 4 Sep 2022 19:49:46 -0400 Subject: Fix 32-bit conditional thumb branches Correct the shift used to select condition bits and correctly compute the branch offset. --- src/armv7/thumb.rs | 16 ++++++++++++++-- tests/armv7/thumb.rs | 4 ++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/armv7/thumb.rs b/src/armv7/thumb.rs index 2e960b1..45151cd 100644 --- a/src/armv7/thumb.rs +++ b/src/armv7/thumb.rs @@ -1491,10 +1491,22 @@ pub fn decode_into::Address, ::Word>>(d if op & 0b0111000 != 0b0111000 { // `Conditional branch` (`A8-332`) // v6T2 - inst.condition = ConditionCode::build(((instr >> 8) & 0b1111) as u8); + let imm11 = lower2[0..11].load::(); + let imm6 = instr2[0..6].load::(); + let s = instr2[10..11].load::(); + let j1 = lower2[13..14].load::(); + let j2 = lower2[11..12].load::(); + let imm = + (imm11 as i32) | + ((imm6 as i32) << 11) | + ((j1 as i32) << 17) | + ((j2 as i32) << 18) | + ((s as i32) << 19); + let imm = (imm << 12) >> 12; + inst.condition = ConditionCode::build(((instr >> 6) & 0b1111) as u8); inst.opcode = Opcode::B; inst.operands = [ - Operand::BranchThumbOffset(((instr & 0b11111111) + 1) as i8 as i32), + Operand::BranchThumbOffset(imm), Operand::Nothing, Operand::Nothing, Operand::Nothing, diff --git a/tests/armv7/thumb.rs b/tests/armv7/thumb.rs index dc912a6..8e1796d 100644 --- a/tests/armv7/thumb.rs +++ b/tests/armv7/thumb.rs @@ -738,6 +738,10 @@ fn test_decode_32b_branch_cases() { &[0x0c, 0xf0, 0x84, 0xb9], "b.w $+0xc308" ); + test_display( + &[0x3f, 0xf4, 0xfe, 0xaf], + "b.weq $-0x4" + ); } #[test] fn test_decode_bkpt_cases() { -- cgit v1.1