packages feed

crackNum 3.25 → 3.26

raw patch · 6 files changed

+364/−217 lines, 6 files

Files

CHANGES.md view
@@ -1,7 +1,33 @@ * Hackage: <http://hackage.haskell.org/package/crackNum> * GitHub:  <http://github.com/LeventErkok/crackNum/> -* Latest Hackage released version: 3.24, 2026-08-17+* Latest Hackage released version: 3.26, 2026-08-19++### Version 3.26, 2026-08-19++  * New flag `--list-formats`, which prints the floating-point formats `-f` accepts,+    one name per line. It is meant for editor integrations, which would otherwise have+    to hardcode the list and let it go stale; the VIM plugin now asks rather than+    guesses, and picks up any format added later for free.++  * `--help` now also lists the supported floating-point formats. Both it and the+    `-f` error message are generated from a single table, so they cannot disagree.++  * Fix the VIM integration, which had been broken since version 3.0. The plugin+    offered `i`, `w`, and `f` as the choices at its precision prompt, and passed+    whichever you picked through as-is, so `:CrackNum` ran `crackNum i 0b0110`:+    no leading dash, and no bit-width. Every invocation was rejected, and the+    quickfix window filled up with crackNum's usage text instead of an answer.+    The completion list now offers real flags (`-i8`, `-fhp`, ...), and anything+    else crackNum accepts, such as `-f3+4` or `-l4 -fhp`, can be typed in directly.++  * The VIM plugin also set `grepformat` to `VIM %m`, matching a `--vim` output+    mode that was removed in 3.0. Nothing matched that format, so even a correct+    invocation produced an empty quickfix window. Take crackNum's output as-is now.++  * The VIM plugin now finds the bit-pattern under the cursor itself, instead of+    relying on `<cword>`. Verilog notation stops at the quote (`64'hdeadbeef` came+    out as just `64`), and the value is quoted before it reaches the shell.  ### Version 3.25, 2026-08-18 
− GUI/tclGUI/README.md
@@ -1,91 +0,0 @@-# CrackNum Tcl/Tk GUI--A cross-platform GUI for [crackNum](https://github.com/LeventErkok/crackNum), written in Tcl/Tk.-Works on Linux and macOS anywhere `wish` (Tk 8.6+) is available.--## Requirements--- `crackNum` on your PATH-- `z3` on your PATH-- `wish` (Tk 8.6+)--On NixOS / Nix:--```bash-nix profile install nixpkgs#tk-```--On Debian/Ubuntu:--```bash-sudo apt install tk-```--On RHEL/Fedora/Rocky:--```bash-sudo dnf install tk-```--## Installation--Nothing to do: this script is a cabal data-file, so `cabal install crackNum`-puts it on disk next to the binary, and `crackNum --gui` finds it there.--If you do not have it — say you only have the binary, or you moved it — get the-sources with either of:--```bash-cabal get crackNum-git clone http://github.com/LeventErkok/crackNum.git-```--### Running a different copy--`crackNum` looks for the script in three places, first match wins:--| Order | Location                             | Use it for                        |-|-------|--------------------------------------|-----------------------------------|-| 1     | `$CRACKNUM_TCL`                      | pointing at an explicit file      |-| 2     | `crackNum.tcl` on your PATH          | shadowing with a checkout         |-| 3     | the copy installed with the package  | the normal case; nothing to set   |--So to test a modified script:--```bash-export CRACKNUM_TCL=/path/to/crackNum/GUI/tclGUI/crackNum.tcl-```--or put its directory on your PATH (the script must be executable for this route):--```bash-export PATH=/path/to/crackNum/GUI/tclGUI:$PATH-```--When working inside a checkout, `cabal run crackNum -- --gui` also works: cabal-sets `crackNum_datadir` so the in-tree copy is used.--## Usage--Launch via the `crackNum` binary:--```bash-crackNum --gui-crackNum --gui -fsp 2.5-crackNum --gui -w32 0xDEADBEEF-```--Or directly with `wish`:--```bash-wish crackNum.tcl-wish crackNum.tcl -fsp 2.5-```--## Keyboard shortcuts--| Key      | Action          |-|----------|-----------------|-| Ctrl+W   | Close window    |-| Ctrl+Q   | Quit            |-| Return   | Crack the value |
README.md view
@@ -23,20 +23,24 @@  ### Supported formats -| Flag        | Format                              | Exponent | Significand (incl. implicit bit) |-|-------------|-------------------------------------|---------:|---------------------------------:|-| `-fhp`      | Half precision (IEEE-754 binary16)  |        5 |                               11 |-| `-fbp`      | Brain float (bfloat16)              |        8 |                                8 |-| `-ftf32`    | TensorFloat-32                      |        8 |                               11 |-| `-fsp`      | Single precision (binary32)         |        8 |                               24 |-| `-fdp`      | Double precision (binary64)         |       11 |                               53 |-| `-fqp`      | Quad precision (binary128)          |       15 |                              113 |-| `-fe5m2`    | FP8, IEEE-754 style                 |        5 |                                3 |-| `-fe4m3`    | FP8, alternate (no infinities)      |        4 |                                4 |-| `-ffp4`     | FP4 (E2M1)                          |        2 |                                2 |-| `-ffp4e0m3` | FP4 (E0M3), sign-magnitude          |        0 |                                3 |-| `-fa+b`     | Arbitrary IEEE-754 float            |        a |                                b |+```+Flag        Format                               Exponent   Significand+-----------------------------------------------------------------------+-fhp        Half precision (IEEE-754 binary16)          5            11+-fbp        Brain float (bfloat16)                      8             8+-ftf32      TensorFloat-32                              8            11+-fsp        Single precision (binary32)                 8            24+-fdp        Double precision (binary64)                11            53+-fqp        Quad precision (binary128)                 15           113+-fe5m2      FP8, IEEE-754 style                         5             3+-fe4m3      FP8, alternate (no infinities)              4             4+-ffp4       FP4 (E2M1)                                  2             2+-ffp4e0m3   FP4 (E0M3), sign-magnitude                  0             3+-fa+b       Arbitrary IEEE-754 float                    a             b+``` +Significand sizes include the implicit bit.+ FP4 (E0M3) is the odd one out: with no exponent bits at all it is really a 4-bit sign-magnitude *integer*, holding a sign and a 3-bit magnitude. It covers -7 to 7, with both a positive and a negative zero, and has neither NaN nor Inf.@@ -348,47 +352,63 @@ ### Usage info ``` Usage: crackNum value OR binary/hex-pattern-  -i N                 Signed   integer of N-bits-  -w N                 Unsigned integer of N-bits-  -f fp                Floating point format fp-  -r rm                Rounding mode to use. If not given, Nearest-ties-to-Even.-  -l lanes             Number of lanes to decode-  -h, -?    --help     print help, with examples-  -v        --version  print version info-  -d        --debug    debug mode, developers only-            --gui      launch the graphical interface+  -i N                      Signed   integer of N-bits+  -w N                      Unsigned integer of N-bits+  -f fp                     Floating point format fp+  -r rm                     Rounding mode to use. If not given, Nearest-ties-to-Even.+  -l lanes                  Number of lanes to decode+  -h, -?    --help          print help, with examples+  -v        --version       print version info+  -d        --debug         debug mode, developers only+            --gui           launch the graphical interface+            --list-formats  list the formats supported by -f, one per line +Supported floating-point formats (for use with -f):++       hp: Half float             ( 5 +  11)+       bp: Brain float            ( 8 +   8)+     tf32: TensorFloat-32         ( 8 +  11)+       sp: Single precision       ( 8 +  24)+       dp: Double precision       (11 +  53)+       qp: Quad   precision       (15 + 113)+      a+b: Arbitrary IEEE-754     ( a +   b)+     e5m2: FP8 format (IEEE-754)  ( 5 +   3)+     e4m3: FP8 format (Alternate) ( 4 +   4)+      fp4: FP4 format (E2M1)      ( 2 +   2)+  fp4e0m3: FP4 format (E0M3)      ( 0 +   3)+ Examples:  Encoding:-   crackNum -i4       -- -2                    -- encode as 4-bit signed integer-   crackNum -w4       2                        -- encode as 4-bit unsigned integer-   crackNum -f3+4     2.5                      -- encode as float with 3 bits exponent, 4 bits significand-   crackNum -f3+4     2.5 -rRTZ                -- encode as above, but use RTZ rounding mode.-   crackNum -fbp      2.5                      -- encode as a brain-precision float-   crackNum -ftf32    2.5                      -- encode as a TensorFloat-32 float-   crackNum -fdp      2.5                      -- encode as a double-precision float-   crackNum -fqp      2.5                      -- encode as a quad-precision float-   crackNum -fe4m3    2.5                      -- encode as an E4M3 FP8 float-   crackNum -fe5m2    2.5                      -- encode as an E5M2 FP8 float-   crackNum -ffp4     2.5                      -- encode as an FP4 (E2M1) float-   crackNum -ffp4e0m3 3.5                      -- encode as an FP4 (E0M3) sign-magnitude integer-   crackNum -fsp      0x3.2p5                  -- encode as single-precision from hex-float+   crackNum -i4       -- -2                   -- encode as 4-bit signed integer+   crackNum -w4       2                       -- encode as 4-bit unsigned integer+   crackNum -f3+4     2.5                     -- encode as float with 3 bits exponent, 4 bits significand+   crackNum -f3+4     2.5 -rRTZ               -- encode as above, but use RTZ rounding mode.+   crackNum -fbp      2.5                     -- encode as a brain-precision float+   crackNum -ftf32    2.5                     -- encode as a TensorFloat-32 float+   crackNum -fdp      2.5                     -- encode as a double-precision float+   crackNum -fqp      2.5                     -- encode as a quad-precision float+   crackNum -fe4m3    2.5                     -- encode as an E4M3 FP8 float+   crackNum -fe5m2    2.5                     -- encode as an E5M2 FP8 float+   crackNum -ffp4     2.5                     -- encode as an FP4 (E2M1) float+   crackNum -ffp4e0m3 3.5                     -- encode as an FP4 (E0M3) sign-magnitude integer+   crackNum -fsp      0x3.2p5                 -- encode as single-precision from hex-float   Decoding:-   crackNum -i4       0b0110                   -- decode as 4-bit signed integer, from binary-   crackNum -w4       0xE                      -- decode as 4-bit unsigned integer, from hex-   crackNum -f3+4     0b0111001                -- decode as float with 3 bits exponent, 4 bits significand-   crackNum -fbp      0x000F                   -- decode as a brain-precision float-   crackNum -ftf32    19\'h0000F               -- decode as a TensorFloat-32 float-   crackNum -fdp      0x8000000000000000       -- decode as a double-precision float-   crackNum -fhp      0x8000                   -- decode as a half-precision float-   crackNum -ffp4     0b0111                   -- decode as an FP4 (E2M1) float-   crackNum -ffp4e0m3 0b1101                   -- decode as an FP4 (E0M3) sign-magnitude integer-   crackNum -l4 -fhp  64\'hbdffaaffdc71fc60    -- decode as half-precision float over 4 lanes using verilog notation+   crackNum -i4       0b0110                  -- decode as 4-bit signed integer, from binary+   crackNum -w4       0xE                     -- decode as 4-bit unsigned integer, from hex+   crackNum -f3+4     0b0111001               -- decode as float with 3 bits exponent, 4 bits significand+   crackNum -fbp      0x000F                  -- decode as a brain-precision float+   crackNum -ftf32    19\'h0000F              -- decode as a TensorFloat-32 float+   crackNum -fdp      0x8000000000000000      -- decode as a double-precision float+   crackNum -fhp      0x8000                  -- decode as a half-precision float+   crackNum -ffp4     0b0111                  -- decode as an FP4 (E2M1) float+   crackNum -ffp4e0m3 0b1101                  -- decode as an FP4 (E0M3) sign-magnitude integer+   crackNum -l4 -fhp  64\'hbdffaaffdc71fc60   -- decode as half-precision float over 4 lanes using verilog notation   GUI:-   crackNum --gui                     -- launch the graphical interface-   crackNum --gui 0xdeadbeef          -- launch the GUI, pre-filled with the given value+   crackNum --gui                             -- launch the graphical interface+   crackNum --gui      0xdeadbeef             -- launch the GUI, pre-filled with the given value+   crackNum --gui -fsp 0xdeadbeef             -- launch the GUI, using the given format   Notes:    - For encoding:
crackNum.cabal view
@@ -1,6 +1,6 @@ Cabal-version      : 2.2 Name               : crackNum-Version            : 3.25+Version            : 3.26 Synopsis           : Crack various integer and floating-point data formats Description        : Crack IEEE-754 and other float formats and arbitrary sized words and integers, showing the layout.                      .@@ -13,7 +13,8 @@ Copyright          : Levent Erkok Category           : Tools Build-type         : Simple-Extra-Source-Files : README.md, COPYRIGHT, CHANGES.md, GUI/tclGUI/README.md+Extra-Source-Files : README.md, COPYRIGHT, crackNum.vim+Extra-Doc-Files    : CHANGES.md  -- The Tcl/Tk GUI is a data-file (not merely an extra-source-file) so that it is -- actually installed alongside the binary, and can be found at run time via
+ crackNum.vim view
@@ -0,0 +1,158 @@+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""+" VI interface to crackNum+"+" Copyright   :  (c) Levent Erkok+" License     :  BSD3+" Maintainer  :  erkokl@gmail.com+"+" INSTALLATION: Put this file in a convenient location (typically your .vim directory),+" and put "so crackNum.vim" in your .vimrc file. (With the appropriate path.)+"+" Once you restart vim, locate your cursor over a stream of binary/hex digits, and+" enter the command :CrackNum to see further options.+"+" Arguments are passed to crackNum verbatim, so anything the executable accepts works:+"+"     :CrackNum -i4              " decode as a 4-bit signed integer+"     :CrackNum -fhp             " decode as a half-precision float+"     :CrackNum -f3+4            " decode as a float with 3 exponent, 4 significand bits+"     :CrackNum -l4 -fhp         " decode 4 lanes of half-precision floats+"+" Use TAB to complete the common formats. With no arguments, :CrackNum prompts for them.+" The formats offered come from "crackNum --list-formats", so they track the executable.+"+" Set g:crackNumProgram to run a crackNum that is not on your PATH, and+" g:crackNumPrecisions to replace the completion list outright.+"+" See https://github.com/LeventErkok/CrackNum for details.++" Which executable to run; override if crackNum is not on your PATH.+if !exists("g:crackNumProgram")+    let g:crackNumProgram = "crackNum"+endif++" Integer widths and lane counts offered by TAB completion. These are only the common+" cases: crackNum takes any -iN/-wN/-lN, and any such argument can be typed in directly.+let s:crackNumIntFlags  = ["-i8", "-i16", "-i32", "-i64", "-w8", "-w16", "-w32", "-w64"]+let s:crackNumLaneFlags = ["-l2", "-l4", "-l8"]++" Used only when crackNum is too old to know --list-formats, or is not on the PATH.+" Anything crackNum has learned since is picked up from the executable, not from here.+let s:crackNumFallbackFormats = [ "hp", "bp", "tf32", "sp", "dp", "qp"+                              \ , "e5m2", "e4m3", "fp4", "fp4e0m3"+                              \ ]++" The formats the executable reports, as -f flags. Asking it keeps this list from+" drifting out of date as crackNum grows new formats. Cached per executable, since+" completion is on a keystroke path and this shells out.+let s:crackNumFormatCache = {}+function! s:CrackNumFormats()+    if has_key(s:crackNumFormatCache, g:crackNumProgram)+        return s:crackNumFormatCache[g:crackNumProgram]+    endif+    let l:names = []+    " 2>&1 so that an older crackNum, which errors out here, cannot scribble on the screen.+    let l:out = systemlist(shellescape(g:crackNumProgram) . " --list-formats 2>&1")+    if v:shell_error == 0+        let l:names = filter(l:out, 'v:val =~# "^[a-z0-9]\\+$"')+    endif+    if empty(l:names)+        let l:names = s:crackNumFallbackFormats+    endif+    let s:crackNumFormatCache[g:crackNumProgram] = map(copy(l:names), '"-f" . v:val')+    return s:crackNumFormatCache[g:crackNumProgram]+endfunction++" What TAB offers. Set g:crackNumPrecisions yourself to override the whole list.+function! s:CrackNumChoices()+    if exists("g:crackNumPrecisions")+        return g:crackNumPrecisions+    endif+    return s:crackNumIntFlags + s:CrackNumFormats() + s:crackNumLaneFlags+endfunction++function! CrackNumComplete(A, L, P)+    let l:all = s:CrackNumChoices()+    if empty(a:A)+        return l:all+    endif+    " Plain prefix match: the arguments contain '-' and '+', so avoid regex matching.+    let l:out = filter(copy(l:all), 'stridx(v:val, a:A) == 0')+    if empty(l:out)+        return l:all+    endif+    return l:out+endfunction++" Patterns crackNum accepts as input, most specific first. Note that <cword> is not+" good enough on its own: it stops at the quote in verilog notation (64'hdeadbeef),+" and <cWORD> is too greedy, picking up trailing punctuation such as "0x8000;".+let s:crackNumPatterns = [ "\\d\\+'[bBoOdDhH][0-9a-fA-F_]\\+"+                       \ , "0[xX][0-9a-fA-F_]\\+"+                       \ , "0[bB][01_]\\+"+                       \ ]++" The bit-pattern under the cursor, falling back on <cword> if nothing matches.+function! s:CrackNumWord()+    let l:line = getline('.')+    let l:idx  = col('.') - 1+    for l:pat in s:crackNumPatterns+        let l:from = 0+        while 1+            let l:m = matchstrpos(l:line, l:pat, l:from)+            if l:m[1] < 0+                break+            endif+            if l:idx >= l:m[1] && l:idx < l:m[2]+                return l:m[0]+            endif+            let l:from = l:m[2]+        endwhile+    endfor+    return expand("<cword>")+endfunction++function! CrackNum(...)+    redraw+    let l:curWord = s:CrackNumWord()+    if empty(l:curWord)+        echoerr "Place the cursor on a bin/hex number to crack!"+        return+    endif+    if empty(a:000)+        echo "Cracking \"" . l:curWord . "\".. Use TAB to see the formats supported."+        call inputsave()+        let l:args = [input("Format> ", "", "customlist,CrackNumComplete")]+        call inputrestore()+        redraw+        if empty(join(l:args, ''))+            echoerr "No format given; use e.g. -i4, -w8, or -fhp."+            return+        endif+    else+        echo "Cracking \""  . l:curWord . "\".."+        let l:args = copy(a:000)+    endif++    " Quote the value: verilog notation (64'hdeadbeef) is not shell-safe as-is.+    let l:grepargs = join(l:args + [shellescape(l:curWord)], ' ')+    let l:grepprg_bak=&grepprg+    let l:grepformat_bak=&grepformat+    try+        let &grepprg=g:crackNumProgram+        " crackNum reports plain text, not file:line diagnostics, so take each line as is.+        let &grepformat="%m"+        silent execute "grep" . " " . l:grepargs+    finally+        let &grepprg=l:grepprg_bak+        let &grepformat=l:grepformat_bak+    endtry++    call setqflist([], 'a', {'title': g:crackNumProgram . ' ' . l:grepargs})++    botright copen++    redraw!+endfunction+command! -nargs=* -complete=customlist,CrackNumComplete CrackNum call CrackNum(<f-args>)+" end crackNum interface
src/CrackNum/Main.hs view
@@ -124,6 +124,7 @@           | Version            -- ^ Version           | Debug              -- ^ Run in debug mode. Debugging only.           | GUI                -- ^ Launch the graphical interface+          | Formats            -- ^ List the floating-point formats we support           | Help               -- ^ Show help           deriving (Show, Eq) @@ -161,6 +162,37 @@ #define FP_MAX_SB 1073741822 #endif +-- | The floating-point formats we support, in the order we present them: the name to+-- pass to -f, what it is, and its (exponent + significand) sizes. The arbitrary format+-- stands in for any a+b pair rather than naming a format of its own, which is what the+-- final field records: only the named ones can be listed as choices.+fpFormats :: [(String, String, String, Bool)]+fpFormats = [ ("hp",      "Half float",             "( 5 +  11)", True )+            , ("bp",      "Brain float",            "( 8 +   8)", True )+            , ("tf32",    "TensorFloat-32",         "( 8 +  11)", True )+            , ("sp",      "Single precision",       "( 8 +  24)", True )+            , ("dp",      "Double precision",       "(11 +  53)", True )+            , ("qp",      "Quad   precision",       "(15 + 113)", True )+            , ("a+b",     "Arbitrary IEEE-754",     "( a +   b)", False)+            , ("e5m2",    "FP8 format (IEEE-754)",  "( 5 +   3)", True )+            , ("e4m3",    "FP8 format (Alternate)", "( 4 +   4)", True )+            , ("fp4",     "FP4 format (E2M1)",      "( 2 +   2)", True )+            , ("fp4e0m3", "FP4 format (E0M3)",      "( 0 +   3)", True )+            ]++-- | The formats that can actually be named, i.e., everything but the arbitrary a+b+-- placeholder. This is what --list-formats prints, one per line.+fpFormatNames :: [String]+fpFormatNames = [n | (n, _, _, True) <- fpFormats]++-- | Floating-point formats we support, as a table for use in help/error messages.+fpFormatsHelp :: [String]+fpFormatsHelp = [rjust n ++ ": " ++ ljust d ++ " " ++ sz | (n, d, sz, _) <- fpFormats]+  where nw      = maximum [length n | (n, _, _, _) <- fpFormats]+        dw      = maximum [length d | (_, d, _, _) <- fpFormats]+        rjust x = replicate (nw - length x) ' ' ++ x+        ljust x = x ++ replicate (dw - length x) ' '+ -- | Given a float flag value, turn it into a flag getFP :: String -> Flag getFP "hp"      = Floating $ FP 5 11@@ -178,23 +210,14 @@                                         (sp@(_:_), "") -> mkEBSB (read eb) (read sp)                                         _              -> bad                   _                 -> bad-                where bad = BadFlag [ "Option " ++ show "-f" ++ " requires one of:"-                                    , ""-                                    , "     hp: Half float             ( 5 +  11)"-                                    , "     bp: Brain float            ( 8 +   8)"-                                    , "   tf32: TensorFloat-32         ( 8 +  11)"-                                    , "     sp: Single precision       ( 8 +  24)"-                                    , "     dp: Double precision       (11 +  53)"-                                    , "     qp: Quad   precision       (15 + 113)"-                                    , "    a+b: Arbitrary IEEE-754     ( a +   b)"-                                    , "   e5m2: FP8 format (IEEE-754)  ( 5 +   3)"-                                    , "   e4m3: FP8 format (Alternate) ( 4 +   4)"-                                    , "    fp4: FP4 format (E2M1)      ( 2 +   2)"-                                    , "fp4e0m3: FP4 format (E0M3)      ( 0 +   3)"-                                    , ""-                                    , "In the arbitrary format, the first number is the number of bits in the exponent"-                                    , "and the second number is the number of bits in the significand, including the implicit bit."-                                    ]+                where bad = BadFlag $ [ "Option " ++ show "-f" ++ " requires one of:"+                                      , ""+                                      ]+                                   ++ fpFormatsHelp+                                   ++ [ ""+                                      , "In the arbitrary format, the first number is the number of bits in the exponent"+                                      , "and the second number is the number of bits in the significand, including the implicit bit."+                                      ]                       mkEBSB :: Int -> Int -> Flag                       mkEBSB eb sb                        |    eb >= FP_MIN_EB && eb <= FP_MAX_EB@@ -227,15 +250,16 @@ -- | Options we accept pgmOptions :: [OptDescr Flag] pgmOptions = [-      Option "i"  []          (ReqArg (getSize "-i" Signed)   "N" )    "Signed   integer of N-bits"-    , Option "w"  []          (ReqArg (getSize "-w" Unsigned) "N" )    "Unsigned integer of N-bits"-    , Option "f"  []          (ReqArg getFP                   "fp")    "Floating point format fp"-    , Option "r"  []          (ReqArg (getRM . map toLower)   "rm")    "Rounding mode to use. If not given, Nearest-ties-to-Even."-    , Option "l"  []          (ReqArg (getSize "-l" Lanes)    "lanes") "Number of lanes to decode"-    , Option "h?" ["help"]    (NoArg Help)                             "print help, with examples"-    , Option "v"  ["version"] (NoArg Version)                          "print version info"-    , Option "d"  ["debug"]   (NoArg Debug)                            "debug mode, developers only"-    , Option ""   ["gui"]     (NoArg GUI)                              "launch the graphical interface"+      Option "i"  []               (ReqArg (getSize "-i" Signed)   "N" )    "Signed   integer of N-bits"+    , Option "w"  []               (ReqArg (getSize "-w" Unsigned) "N" )    "Unsigned integer of N-bits"+    , Option "f"  []               (ReqArg getFP                   "fp")    "Floating point format fp"+    , Option "r"  []               (ReqArg (getRM . map toLower)   "rm")    "Rounding mode to use. If not given, Nearest-ties-to-Even."+    , Option "l"  []               (ReqArg (getSize "-l" Lanes)    "lanes") "Number of lanes to decode"+    , Option "h?" ["help"]         (NoArg Help)                             "print help, with examples"+    , Option "v"  ["version"]      (NoArg Version)                          "print version info"+    , Option "d"  ["debug"]        (NoArg Debug)                            "debug mode, developers only"+    , Option ""   ["gui"]          (NoArg GUI)                              "launch the graphical interface"+    , Option ""   ["list-formats"] (NoArg Formats)                          "list the formats supported by -f, one per line"     ]  -- | Help info@@ -244,56 +268,62 @@  -- | Print usage info and examples. usage :: String -> IO ()-usage pn = putStr $ unlines [ helpStr pn-                            , "Examples:"-                            , " Encoding:"-                            , "   " ++ pn ++ " -i4    -- -2                    -- encode as 4-bit signed integer"-                            , "   " ++ pn ++ " -w4    2                        -- encode as 4-bit unsigned integer"-                            , "   " ++ pn ++ " -f3+4  2.5                      -- encode as float with 3 bits exponent, 4 bits significand"-                            , "   " ++ pn ++ " -f3+4  2.5 -rRTZ                -- encode as above, but use RTZ rounding mode."-                            , "   " ++ pn ++ " -fbp   2.5                      -- encode as a brain-precision float"-                            , "   " ++ pn ++ " -ftf32 2.5                      -- encode as a TensorFloat-32 float"-                            , "   " ++ pn ++ " -fdp   2.5                      -- encode as a double-precision float"-                            , "   " ++ pn ++ " -fqp   2.5                      -- encode as a quad-precision float"-                            , "   " ++ pn ++ " -fe4m3 2.5                      -- encode as an E4M3 FP8 float"-                            , "   " ++ pn ++ " -fe5m2 2.5                      -- encode as an E5M2 FP8 float"-                            , "   " ++ pn ++ " -ffp4  2.5                      -- encode as an FP4 (E2M1) float"-                            , "   " ++ pn ++ " -ffp4e0m3 3.5                   -- encode as an FP4 (E0M3) sign-magnitude integer"-                            , "   " ++ pn ++ " -fsp   0x3.2p5                  -- encode as single-precision from hex-float"-                            , ""-                            , " Decoding:"-                            , "   " ++ pn ++ " -i4      0b0110                -- decode as 4-bit signed integer, from binary"-                            , "   " ++ pn ++ " -w4      0xE                   -- decode as 4-bit unsigned integer, from hex"-                            , "   " ++ pn ++ " -f3+4    0b0111001             -- decode as float with 3 bits exponent, 4 bits significand"-                            , "   " ++ pn ++ " -fbp     0x000F                -- decode as a brain-precision float"-                            , "   " ++ pn ++ " -ftf32   19\\'h0000F            -- decode as a TensorFloat-32 float"-                            , "   " ++ pn ++ " -fdp     0x8000000000000000    -- decode as a double-precision float"-                            , "   " ++ pn ++ " -fhp     0x8000                -- decode as a half-precision float"-                            , "   " ++ pn ++ " -ffp4    0b0111                -- decode as an FP4 (E2M1) float"-                            , "   " ++ pn ++ " -ffp4e0m3 0b1101               -- decode as an FP4 (E0M3) sign-magnitude integer"-                            , "   " ++ pn ++ " -l4 -fhp 64\\'hbdffaaffdc71fc60 -- decode as half-precision float over 4 lanes using verilog notation"-                            , ""-                            , " GUI:"-                            , "   " ++ pn ++ " --gui                     -- launch the graphical interface"-                            , "   " ++ pn ++ " --gui 0xdeadbeef          -- launch the GUI, pre-filled with the given value"-                            , ""-                            , " Notes:"-                            , "   - For encoding:"-                            , "       - Use -- to separate your argument if it's a negative number."-                            , "       - For floats: You can pass in NaN, Inf, -0, -Inf etc as the argument"-                            , "                     along with a decimal (2.3, -4.1e5) or hexadecimal float (0x2.4p3)"-                            , "       - FP4 (E2M1) has neither NaN nor Inf, so those inputs are rejected. Finite"-                            , "         values outside its range of [-6, 6] saturate to the nearest end-point."-                            , "       - FP4 (E0M3) is a sign-magnitude integer: a sign bit and a 3-bit magnitude,"-                            , "         covering -7 to 7, with both a positive and a negative zero. It has no NaN"-                            , "         and no Inf either, and values outside [-7, 7] saturate to the end-point."-                            , "   - For decoding:"-                            , "       - Use hexadecimal (0x) binary (0b), or N'h (verilog) notation as input."-                            , "         Input must have one of these prefixes."-                            , "       - You can use _,- or space as a digit to improve readability for the pattern to be decoded"-                            , "       - With -lN parameter, you can decode multiple lanes of data."-                            , "       - If you use verilog input format, then we will infer the number of lanes unless you provide it."-                            ]+usage pn = putStr $ unlines $ [ helpStr pn+                              , "Supported floating-point formats (for use with -f):"+                              , ""+                              ]+                           ++ map ("  " ++) fpFormatsHelp+                           ++ [ ""+                              , "Examples:"+                              , " Encoding:"+                              , "   " ++ pn ++ " -i4       -- -2                   -- encode as 4-bit signed integer"+                              , "   " ++ pn ++ " -w4       2                       -- encode as 4-bit unsigned integer"+                              , "   " ++ pn ++ " -f3+4     2.5                     -- encode as float with 3 bits exponent, 4 bits significand"+                              , "   " ++ pn ++ " -f3+4     2.5 -rRTZ               -- encode as above, but use RTZ rounding mode."+                              , "   " ++ pn ++ " -fbp      2.5                     -- encode as a brain-precision float"+                              , "   " ++ pn ++ " -ftf32    2.5                     -- encode as a TensorFloat-32 float"+                              , "   " ++ pn ++ " -fdp      2.5                     -- encode as a double-precision float"+                              , "   " ++ pn ++ " -fqp      2.5                     -- encode as a quad-precision float"+                              , "   " ++ pn ++ " -fe4m3    2.5                     -- encode as an E4M3 FP8 float"+                              , "   " ++ pn ++ " -fe5m2    2.5                     -- encode as an E5M2 FP8 float"+                              , "   " ++ pn ++ " -ffp4     2.5                     -- encode as an FP4 (E2M1) float"+                              , "   " ++ pn ++ " -ffp4e0m3 3.5                     -- encode as an FP4 (E0M3) sign-magnitude integer"+                              , "   " ++ pn ++ " -fsp      0x3.2p5                 -- encode as single-precision from hex-float"+                              , ""+                              , " Decoding:"+                              , "   " ++ pn ++ " -i4       0b0110                  -- decode as 4-bit signed integer, from binary"+                              , "   " ++ pn ++ " -w4       0xE                     -- decode as 4-bit unsigned integer, from hex"+                              , "   " ++ pn ++ " -f3+4     0b0111001               -- decode as float with 3 bits exponent, 4 bits significand"+                              , "   " ++ pn ++ " -fbp      0x000F                  -- decode as a brain-precision float"+                              , "   " ++ pn ++ " -ftf32    19\\'h0000F              -- decode as a TensorFloat-32 float"+                              , "   " ++ pn ++ " -fdp      0x8000000000000000      -- decode as a double-precision float"+                              , "   " ++ pn ++ " -fhp      0x8000                  -- decode as a half-precision float"+                              , "   " ++ pn ++ " -ffp4     0b0111                  -- decode as an FP4 (E2M1) float"+                              , "   " ++ pn ++ " -ffp4e0m3 0b1101                  -- decode as an FP4 (E0M3) sign-magnitude integer"+                              , "   " ++ pn ++ " -l4 -fhp  64\\'hbdffaaffdc71fc60   -- decode as half-precision float over 4 lanes using verilog notation"+                              , ""+                              , " GUI:"+                              , "   " ++ pn ++ " --gui                             -- launch the graphical interface"+                              , "   " ++ pn ++ " --gui      0xdeadbeef             -- launch the GUI, pre-filled with the given value"+                              , "   " ++ pn ++ " --gui -fsp 0xdeadbeef             -- launch the GUI, using the given format"+                              , ""+                              , " Notes:"+                              , "   - For encoding:"+                              , "       - Use -- to separate your argument if it's a negative number."+                              , "       - For floats: You can pass in NaN, Inf, -0, -Inf etc as the argument"+                              , "                     along with a decimal (2.3, -4.1e5) or hexadecimal float (0x2.4p3)"+                              , "       - FP4 (E2M1) has neither NaN nor Inf, so those inputs are rejected. Finite"+                              , "         values outside its range of [-6, 6] saturate to the nearest end-point."+                              , "       - FP4 (E0M3) is a sign-magnitude integer: a sign bit and a 3-bit magnitude,"+                              , "         covering -7 to 7, with both a positive and a negative zero. It has no NaN"+                              , "         and no Inf either, and values outside [-7, 7] saturate to the end-point."+                              , "   - For decoding:"+                              , "       - Use hexadecimal (0x) binary (0b), or N'h (verilog) notation as input."+                              , "         Input must have one of these prefixes."+                              , "       - You can use _,- or space as a digit to improve readability for the pattern to be decoded"+                              , "       - With -lN parameter, you can decode multiple lanes of data."+                              , "       - If you use verilog input format, then we will infer the number of lanes unless you provide it."+                              ]  -- | Terminate early die :: [String] -> IO a@@ -409,6 +439,9 @@                   (_,  _,  errs@(_:_)) -> die $ errs ++ lines (helpStr pn)                   (os, rs, [])                     | Version `elem` os -> putStrLn $ pn ++ " v" ++ showVersion version ++ ", " ++ copyRight+                    -- NB. Machine readable, one name per line: this is what the editor+                    -- integrations use so they need not hardcode the list of formats.+                    | Formats `elem` os -> mapM_ putStrLn fpFormatNames                     | Help    `elem` os -> usage pn                     -- NB. Check for bad flags before launching: otherwise a typo like                     -- "-ft32" would silently bring the GUI up with nothing selected.