crackNum 3.25 → 3.26
raw patch · 6 files changed
+364/−217 lines, 6 files
Files
- CHANGES.md +27/−1
- GUI/tclGUI/README.md +0/−91
- README.md +67/−47
- crackNum.cabal +3/−2
- crackNum.vim +158/−0
- src/CrackNum/Main.hs +109/−76
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.