fix: restore iota blocks, asm --format flag and prose after the syntax pass
This commit is contained in:
+30
-30
@@ -299,7 +299,7 @@ given.
|
||||
rc = 1
|
||||
continue
|
||||
}
|
||||
out := format.Source(path, src)
|
||||
out := format.Source(src)
|
||||
if dirMode || *write {
|
||||
if out != src {
|
||||
if err := os.WriteFile(path, []byte(out), 0o644); err != nil {
|
||||
@@ -447,7 +447,7 @@ requires -p, the package path, and the installed Go toolchain).
|
||||
return 1
|
||||
}
|
||||
|
||||
img, err := assembleFile(path, targetArch, f)
|
||||
img, err := assembleFile(targetArch, f)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "%s: %v\n", path, err)
|
||||
return 1
|
||||
@@ -544,7 +544,7 @@ requires -p, the package path, and the installed Go toolchain).
|
||||
|
||||
// cmdDiff compares the machine code of two assembly files.
|
||||
func cmdDiff(args []string) int {
|
||||
fs := newCommand("diff", "gasm diff <file1.s> <file2.s>", `
|
||||
set := newCommand("diff", "gasm diff <file1.s> <file2.s>", `
|
||||
Compare the machine code produced by assembling two files.
|
||||
Shows which functions differ and the byte-level differences.
|
||||
Useful for verifying that two implementations produce identical code,
|
||||
@@ -553,13 +553,13 @@ or for tracking encoding changes between Go assembler versions.
|
||||
Use --map to compare functions whose names differ between the files,
|
||||
e.g. --map wideCopyAVX2=wideCopyAVX512 pairs the two regardless of suffix.
|
||||
`)
|
||||
mapSpec := fs.String("map", "", "comma-separated old=new pairs to match functions with different names")
|
||||
fs.Parse(args)
|
||||
if fs.NArg() != 2 {
|
||||
mapSpec := set.String("map", "", "comma-separated old=new pairs to match functions with different names")
|
||||
set.Parse(args)
|
||||
if set.NArg() != 2 {
|
||||
fmt.Fprintln(os.Stderr, "usage: gasm diff <file1.s> <file2.s>")
|
||||
return 2
|
||||
}
|
||||
path1, path2 := fs.Arg(0), fs.Arg(1)
|
||||
path1, path2 := set.Arg(0), set.Arg(1)
|
||||
|
||||
// Parse the name mapping (file1 name → file2 name).
|
||||
nameMap := make(map[string]string)
|
||||
@@ -640,7 +640,7 @@ e.g. --map wideCopyAVX2=wideCopyAVX512 pairs the two regardless of suffix.
|
||||
}
|
||||
|
||||
// assembleFile assembles a parsed file for the given architecture and returns the image.
|
||||
func assembleFile(path string, targetArch arch.Arch, f *ast.File) (*asm.Image, error) {
|
||||
func assembleFile(targetArch arch.Arch, f *ast.File) (*asm.Image, error) {
|
||||
switch targetArch {
|
||||
case arch.AMD64:
|
||||
return asm.AssembleFile(f)
|
||||
@@ -668,7 +668,7 @@ func assemblePath(path string) (*asm.Image, error) {
|
||||
if len(errs) > 0 {
|
||||
return nil, fmt.Errorf("parse errors")
|
||||
}
|
||||
return assembleFile(path, arch.FromFilename(path), f)
|
||||
return assembleFile(arch.FromFilename(path), f)
|
||||
}
|
||||
|
||||
// printByteDiff shows the first few byte differences between two code blocks.
|
||||
@@ -688,18 +688,18 @@ func printByteDiff(a, b []byte) {
|
||||
|
||||
// cmdProfile shows the basic-block structure of functions in an assembly file.
|
||||
func cmdProfile(args []string) int {
|
||||
fs := newCommand("profile", "gasm profile <file.s>", `
|
||||
flagSet := newCommand("profile", "gasm profile <file.s>", `
|
||||
Show the basic-block structure of functions in an assembly file.
|
||||
Lists each function's labels, their offsets, and the block boundaries.
|
||||
This is the static structure; for runtime execution counts, use
|
||||
gasm verify --fuzz which exercises the code paths.
|
||||
`)
|
||||
fs.Parse(args)
|
||||
if fs.NArg() != 1 {
|
||||
flagSet.Parse(args)
|
||||
if flagSet.NArg() != 1 {
|
||||
fmt.Fprintln(os.Stderr, "usage: gasm profile <file.s>")
|
||||
return 2
|
||||
}
|
||||
path := fs.Arg(0)
|
||||
path := flagSet.Arg(0)
|
||||
|
||||
// Load the file to get function metadata.
|
||||
k, err := verify.Load(path)
|
||||
@@ -1021,7 +1021,7 @@ func cmdVerifyARM64(path string, groundTruth, profile bool) int {
|
||||
}
|
||||
|
||||
func cmdVerify(args []string) int {
|
||||
fs := newCommand("verify", "gasm verify [-smoke] [-abi] [-fuzz] [-ground-truth] [-profile] [-call] <file.s>", `
|
||||
set := newCommand("verify", "gasm verify [-smoke] [-abi] [-fuzz] [-ground-truth] [-profile] [-call] <file.s>", `
|
||||
Assemble FILE (amd64), map it into executable memory and report the available
|
||||
functions. This confirms the assembled image is self-consistent (no
|
||||
unresolved external symbols) and executable — the prerequisite for dynamic
|
||||
@@ -1047,25 +1047,25 @@ With -call, a single function is invoked with user-supplied buffers (-buf)
|
||||
instead of the smoke/abi/fuzz sweeps. Useful for partial functions (e.g.
|
||||
decoders) that crash on random input but should succeed on valid data.
|
||||
`)
|
||||
smoke := fs.Bool("smoke", false, "call each NOSPLIT function with zeroed args")
|
||||
abi := fs.Bool("abi", false, "run ABI-checking calls (sentinel registers + red zone)")
|
||||
abiN := fs.Int("abi-n", 100, "number of ABI check iterations with varied inputs")
|
||||
profile := fs.Bool("profile", false, "list basic-block structure per function")
|
||||
groundTruth := fs.Bool("ground-truth", false, "compare machine code byte-for-byte against go tool asm")
|
||||
fuzz := fs.Bool("fuzz", false, "differential fuzz: JIT both gasm and go-tool-asm versions, compare outputs")
|
||||
fuzzN := fs.Int("n", 1000, "number of fuzz iterations per function")
|
||||
fuzzOne := fs.String("fuzz-one", "", "") // hidden: fuzz a single function (subprocess mode)
|
||||
sweepOne := fs.String("sweep-one", "", "") // hidden: smoke/abi a single function (subprocess mode)
|
||||
call := fs.String("call", "", "call a single function with -buf instead of the sweeps")
|
||||
bufSpec := fs.String("buf", "", "buffer spec for -call: name:size:pattern[,name:size:pattern] (zero, ones, seq, or hex)")
|
||||
scalarSpec := fs.String("args", "", "scalar args for -call: name=value[,name=value] (decimal or 0x hex)")
|
||||
repeat := fs.Int("repeat", 1, "number of times to repeat a -call invocation")
|
||||
fs.Parse(args)
|
||||
if fs.NArg() != 1 {
|
||||
smoke := set.Bool("smoke", false, "call each NOSPLIT function with zeroed args")
|
||||
abi := set.Bool("abi", false, "run ABI-checking calls (sentinel registers + red zone)")
|
||||
abiN := set.Int("abi-n", 100, "number of ABI check iterations with varied inputs")
|
||||
profile := set.Bool("profile", false, "list basic-block structure per function")
|
||||
groundTruth := set.Bool("ground-truth", false, "compare machine code byte-for-byte against go tool asm")
|
||||
fuzz := set.Bool("fuzz", false, "differential fuzz: JIT both gasm and go-tool-asm versions, compare outputs")
|
||||
fuzzN := set.Int("n", 1000, "number of fuzz iterations per function")
|
||||
fuzzOne := set.String("fuzz-one", "", "") // hidden: fuzz a single function (subprocess mode)
|
||||
sweepOne := set.String("sweep-one", "", "") // hidden: smoke/abi a single function (subprocess mode)
|
||||
call := set.String("call", "", "call a single function with -buf instead of the sweeps")
|
||||
bufSpec := set.String("buf", "", "buffer spec for -call: name:size:pattern[,name:size:pattern] (zero, ones, seq, or hex)")
|
||||
scalarSpec := set.String("args", "", "scalar args for -call: name=value[,name=value] (decimal or 0x hex)")
|
||||
repeat := set.Int("repeat", 1, "number of times to repeat a -call invocation")
|
||||
set.Parse(args)
|
||||
if set.NArg() != 1 {
|
||||
fmt.Fprintln(os.Stderr, "usage: gasm verify [-smoke] [-abi] [-fuzz] [-ground-truth] [-profile] [-call] <file.s>")
|
||||
return 2
|
||||
}
|
||||
path := fs.Arg(0)
|
||||
path := set.Arg(0)
|
||||
targetArch := arch.FromFilename(path)
|
||||
switch targetArch {
|
||||
case arch.AMD64:
|
||||
|
||||
Reference in New Issue
Block a user