From 40743d84ffc8bbe0a4e24b9af4d65d58a1367b23 Mon Sep 17 00:00:00 2001 From: Grond Date: Tue, 23 Jun 2026 14:02:51 -0700 Subject: Fix the handling of arithmetic register shifts with zero immediates --- src/armv7.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'src/armv7.rs') diff --git a/src/armv7.rs b/src/armv7.rs index 2ce8122..f911388 100644 --- a/src/armv7.rs +++ b/src/armv7.rs @@ -389,8 +389,31 @@ pub struct RegImmShift { impl RegImmShift { /// the immediate this register is shifted by. pub fn imm(&self) -> u8 { - (self.data >> 7) as u8 & 0b11111 + let raw = (self.data >> 7) as u8 & 0b11111; + // in the ARMv7m reference, + // `Instruction Details` -> + // `Shifts applied to a register` -> + // `Constant shifts`: + // + // > The assembler encodes into two type bits and five immediate bits, as follows: + // > ... + // > LSR # type = 0b01 + // > If < 32, immediate = . + // > If == 32, immediate = 0. + // > ASR # type = 0b10 + // > If < 32, immediate = . + // > If == 32, immediate = 0. + // + // so we have to fix this up here. + if raw == 0 { + let stype = self.stype(); + if stype == ShiftStyle::LSR || stype == ShiftStyle::ASR { + return 32; + } + } + raw } + /// the way in which this register is shifted. pub fn stype(&self) -> ShiftStyle { ShiftStyle::from((self.data >> 5) as u8 & 0b11) -- cgit v1.1