testDecoderThumb = 
  do let f = thumbDecode
     rs <- fmap (take 1000 . randoms) getStdGen
     let ws = map fromIntegral (rs :: [Int]) 
     insns <- disassemble16 "/Users/pumpkin/summon-arm-toolchain/sources/src/binutils/objdump" ["-b", "binary", "-m", "arm", "-M", "force-thumb"] ws
     let ours = map (\(_, x) -> either i16 i32 x) insns
     let tests = zipWith4 (\off w o u -> testCase (printf "0x%04x: %s %s" off w u) (ualMatches off o u)) [0,2..] (map (either (printf "%04x\t\t" :: Word16 -> String) (uncurry (printf "%04x %04x\t")) . snd) insns) ours (map fst insns)
     return $ testGroup ("Thumb decoder") tests
  where i16 :: Word16 -> GeneralInstruction UAL
        i16 i = case thumbDecode i of
                  Done x -> x
                  Word16 _ -> error "decoded 16-bit instruction to larger instruction"

        i32 :: (Word16, Word16) -> GeneralInstruction UAL
        i32 (i0, i1) = case thumbDecode i0 of
                         Done x -> error $ "decoded 32-bit instruction to smaller instruction (" ++ show x ++ ")"
                         Word16 f -> case f i1 of
                                       Done x -> x
                                       Word16 _ -> error "decoded 32-bit instruction to larger instruction"
testDecoderThumb = 
  do let f = thumbDecode
     rs <- fmap (take 1000 . randoms) getStdGen
     let ws = map fromIntegral (rs :: [Int]) 
     insns <- disassemble16 "/Users/pumpkin/summon-arm-toolchain/sources/src/binutils/objdump" ["-b", "binary", "-m", "arm", "-M", "force-thumb"] ws
     let ours = map (\(_, x) -> either i16 i32 x) insns
     let tests = zipWith4 (\off w o u -> testCase (printf "0x%04x: %s %s" off w u) (ualMatches off o u)) [0,2..] (map (either (printf "%04x\t\t" :: Word16 -> String) (uncurry (printf "%04x %04x\t")) . snd) insns) ours (map fst insns)
     return $ testGroup ("Thumb decoder") tests
  where i16 :: Word16 -> GeneralInstruction UAL
        i16 i = case thumbDecode i of
                  Done x -> x
                  Word16 _ -> error "decoded 16-bit instruction to larger instruction"

        i32 :: (Word16, Word16) -> GeneralInstruction UAL
        i32 (i0, i1) = case thumbDecode i0 of
                         Done x -> error $ "decoded 32-bit instruction to smaller instruction (" ++ show x ++ ")"
                         Word16 f -> case f i1 of
                                       Done x -> x
                                       Word16 _ -> error "decoded 32-bit instruction to larger instruction"
testDecoderThumb = 
  do let f = thumbDecode
     rs <- fmap (take 1000 . randoms) getStdGen
     let ws = map fromIntegral (rs :: [Int]) 
     insns <- disassemble16 "/Users/pumpkin/summon-arm-toolchain/sources/src/binutils/objdump" ["-b", "binary", "-m", "arm", "-M", "force-thumb"] ws
     let ours = map (\(_, x) -> either i16 i32 x) insns
     let tests = zipWith4 (\off w o u -> testCase (printf "0x%04x: %s %s" off w u) (ualMatches off o u)) [0,2..] (map (either (printf "%04x\t\t" :: Word16 -> String) (uncurry (printf "%04x %04x\t")) . snd) insns) ours (map fst insns)
     return $ testGroup ("Thumb decoder") tests
  where i16 :: Word16 -> GeneralInstruction UAL
        i16 i = case thumbDecode i of
                  Done x -> x
                  Word16 _ -> error "decoded 16-bit instruction to larger instruction"

        i32 :: (Word16, Word16) -> GeneralInstruction UAL
        i32 (i0, i1) = case thumbDecode i0 of
                         Done x -> error $ "decoded 32-bit instruction to smaller instruction (" ++ show x ++ ")"
                         Word16 f -> case f i1 of
                                       Done x -> x
                                       Word16 _ -> error "decoded 32-bit instruction to larger instruction"