(opcode: u16, address: u64, code: &[u8])
| 144 | } |
| 145 | |
| 146 | fn branch_dest(opcode: u16, address: u64, code: &[u8]) -> Option<u64> { |
| 147 | const OPCODE_B: u16 = opcode_to_u16(Opcode::B); |
| 148 | const OPCODE_BL: u16 = opcode_to_u16(Opcode::BL); |
| 149 | const OPCODE_BCC: u16 = opcode_to_u16(Opcode::Bcc(0)); |
| 150 | const OPCODE_CBZ: u16 = opcode_to_u16(Opcode::CBZ); |
| 151 | const OPCODE_CBNZ: u16 = opcode_to_u16(Opcode::CBNZ); |
| 152 | const OPCODE_TBZ: u16 = opcode_to_u16(Opcode::TBZ); |
| 153 | const OPCODE_TBNZ: u16 = opcode_to_u16(Opcode::TBNZ); |
| 154 | |
| 155 | let word = u32::from_le_bytes(code.try_into().ok()?); |
| 156 | match opcode { |
| 157 | OPCODE_B | OPCODE_BL => { |
| 158 | let offset = ((word & 0x03ff_ffff) << 2) as i32; |
| 159 | let extended_offset = (offset << 4) >> 4; |
| 160 | address.checked_add_signed(extended_offset as i64) |
| 161 | } |
| 162 | OPCODE_BCC | OPCODE_CBZ | OPCODE_CBNZ => { |
| 163 | let offset = (word as i32 & 0x00ff_ffe0) >> 3; |
| 164 | let extended_offset = (offset << 11) >> 11; |
| 165 | address.checked_add_signed(extended_offset as i64) |
| 166 | } |
| 167 | OPCODE_TBZ | OPCODE_TBNZ => { |
| 168 | let offset = (word as i32 & 0x0007_ffe0) >> 3; |
| 169 | let extended_offset = (offset << 16) >> 16; |
| 170 | address.checked_add_signed(extended_offset as i64) |
| 171 | } |
| 172 | _ => None, |
| 173 | } |
| 174 | } |
| 175 | |
| 176 | struct DisplayCtx<'a> { |
| 177 | address: u64, |
no test coverage detected