commit 353732bf0225db2e4289c805f584dd3e7ec64c2f
parent ad414ca37a6c33d3b13606bdabd72cb22c296357
Author: Jared Tobin <jared@jtobin.io>
Date: Sun, 17 May 2026 21:06:04 -0230
parser: collapse pImmShifted to reuse Shift ADT
pImmShiftOp / ImmShiftOp duplicated the existing Shift parser
(pShift) and ADT. Replace with a direct pComma *> pShift and pattern
match on LSL/LSR/ASR, dropping the parallel type and parser.
Also fix the misleading "LSR on a literal: arithmetic floor div"
comment: AArch64 only encodes lsl #0 or lsl #12 on the uimm12
shifted-immediate form; LSR/ASR don't appear here. We accept them
defensively and fold via floor division, which matches ASR
semantics for the small non-negative values these fields hold.
LSR semantics on an unbounded Integer aren't well-defined, so the
unreachable-in-practice caveat is documented in the Haddock.
Diffstat:
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/lib/Audit/AArch64/Parser.hs b/lib/Audit/AArch64/Parser.hs
@@ -404,26 +404,21 @@ pOperand = choice
-- | Like pImm but accepts the AArch64 shifted-immediate form
-- (e.g., @#16, lsl #12@) and folds the shift into the value.
--- Only LSL/LSR/ASR by an explicit amount are recognised.
+--
+-- In practice AArch64 only encodes @lsl #0@ or @lsl #12@ on uimm12
+-- fields (e.g., add/adds/sub/subs/cmp/cmn shifted-immediate); LSR/ASR
+-- never appear in this position. We accept them defensively and treat
+-- both as floor division (semantically equivalent to ASR for the
+-- small non-negative values these fields hold).
pImmShifted :: Parser Integer
pImmShifted = do
n <- pImm
- mSh <- optional (try (pComma *> pImmShiftOp))
+ mSh <- optional (try (pComma *> pShift))
pure $ case mSh of
Nothing -> n
- Just (op, k) -> case op of
- ShL -> n * (2 ^ k)
- ShR -> n `div` (2 ^ k) -- LSR on a literal: arithmetic floor div
- ShA -> n `div` (2 ^ k) -- ASR likewise (sign preserved by div)
-
-data ImmShiftOp = ShL | ShR | ShA
-
-pImmShiftOp :: Parser (ImmShiftOp, Int)
-pImmShiftOp = lexeme $ choice
- [ (,) ShL <$> (string' "lsl" *> sc *> pShiftAmt)
- , (,) ShR <$> (string' "lsr" *> sc *> pShiftAmt)
- , (,) ShA <$> (string' "asr" *> sc *> pShiftAmt)
- ]
+ Just (LSL k) -> n * (2 ^ k)
+ Just (LSR k) -> n `div` (2 ^ k)
+ Just (ASR k) -> n `div` (2 ^ k)
-- Parse register once, then optionally check for shift suffix.
pRegOrShiftedReg :: Parser Operand