diff options
| author | Mitchell Johnson <ehntoo@ehntoo.org> | 2022-09-04 19:49:46 -0400 | 
|---|---|---|
| committer | iximeow <git@iximeow.net> | 2022-09-29 15:50:31 -0700 | 
| commit | 9570dae514462f4a823e54de11e6dc86587de1b7 (patch) | |
| tree | a4b4793490f0aec4ab5d163e7e29c97b530bd6ac | |
| parent | 4470c5b393817a93854472354d76911cfc9abe6f (diff) | |
Fix 32-bit conditional thumb branches
Correct the shift used to select condition bits and correctly compute the
branch offset.
| -rw-r--r-- | src/armv7/thumb.rs | 16 | ||||
| -rw-r--r-- | 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<T: Reader<<ARMv7 as Arch>::Address, <ARMv7 as Arch>::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::<u32>(); +                        let imm6 = instr2[0..6].load::<u32>(); +                        let s = instr2[10..11].load::<u32>(); +                        let j1 = lower2[13..14].load::<u32>(); +                        let j2 = lower2[11..12].load::<u32>(); +                        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() { | 
