diff --git a/.golangci.yml b/.golangci.yml index 4395b4c..b39c88b 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -4,17 +4,34 @@ run: linters: enable-all: true disable: - - funlen - - maligned - - lll - - gosec - - prealloc - - unparam - - gochecknoglobals - - gochecknoinits - - gomnd - - wsl - - godox + - cyclop + - errname + - exhaustivestruct + - forbidigo + - forcetypeassert + - funlen + - gochecknoglobals + - gochecknoinits + - godox + - goerr113 + - golint + - gomnd + - gosec + - ifshort + - interfacer + - ireturn + - lll + - maligned + - nlreturn + - paralleltest + - prealloc + - scopelint + - tagliatelle + - testpackage + - unparam + - varnamelen + - wrapcheck + - wsl linters-settings: depguard: @@ -22,6 +39,11 @@ linters-settings: packages: - github.com/mmcloughlin/avo - golang.org/x/ + gci: + sections: + - standard + - default + - prefix(github.com/mmcloughlin/avo) issues: exclude-use-default: false @@ -29,6 +51,6 @@ issues: # errcheck: Almost all programs ignore errors on these functions and in most cases it's ok - Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked # gocritic: https://github.com/go-critic/go-critic/issues/762 - - ' with `(len|cap|real|imag)`' + - " with `(len|cap|real|imag)`" # We want to allow all caps in certain cases. - "ALL_CAPS in Go names" diff --git a/attr/make_textflag.go b/attr/make_textflag.go index 0d2eb06..eb7f7e3 100644 --- a/attr/make_textflag.go +++ b/attr/make_textflag.go @@ -107,7 +107,7 @@ func DownloadGoSourceFile(outpath, v, srcpath string) (err error) { return err } - if err := ioutil.WriteFile(outpath, buf.Bytes(), 0644); err != nil { + if err := ioutil.WriteFile(outpath, buf.Bytes(), 0o644); err != nil { return err } diff --git a/build/error.go b/build/error.go index 1da00cb..d6f3be6 100644 --- a/build/error.go +++ b/build/error.go @@ -1,6 +1,7 @@ package build import ( + "errors" "fmt" "log" @@ -45,7 +46,8 @@ func (e *ErrorList) AddAt(p src.Position, err error) { e.Add(Error{p, err}) } -// addext appends an error to the list, tagged with the +// addext appends an error to the list, tagged with the first external position +// outside this package. func (e *ErrorList) addext(err error) { e.Add(exterr(err)) } @@ -59,7 +61,7 @@ func (e ErrorList) Err() error { return e } -// An ErrorList implements the error interface. +// Error implements the error interface. func (e ErrorList) Error() string { switch len(e) { case 0: @@ -74,7 +76,8 @@ func (e ErrorList) Error() string { // an ErrorList. Otherwise it just logs the err string. Reports at most max // errors, or unlimited if max is 0. func LogError(l *log.Logger, err error, max int) { - if list, ok := err.(ErrorList); ok { + var list ErrorList + if errors.As(err, &list) { for i, e := range list { if max > 0 && i == max { l.Print("too many errors") diff --git a/build/error_test.go b/build/error_test.go index 4d46942..0428ebb 100644 --- a/build/error_test.go +++ b/build/error_test.go @@ -63,7 +63,7 @@ func TestLogErrorList(t *testing.T) { for i := 1; i <= m; i++ { expect += fmt.Sprintf("prefix: %s:%d: some kind of error\n", filename, i) } - expect += fmt.Sprintf("prefix: too many errors\n") + expect += "prefix: too many errors\n" got := buf.String() if got != expect { diff --git a/build/global.go b/build/global.go index e23da2c..3a1690c 100644 --- a/build/global.go +++ b/build/global.go @@ -9,7 +9,6 @@ import ( "github.com/mmcloughlin/avo/gotypes" "github.com/mmcloughlin/avo/ir" "github.com/mmcloughlin/avo/operand" - "github.com/mmcloughlin/avo/reg" ) diff --git a/build/pseudo.go b/build/pseudo.go index 83a570e..009811d 100644 --- a/build/pseudo.go +++ b/build/pseudo.go @@ -2,10 +2,9 @@ package build import ( "github.com/mmcloughlin/avo/attr" + "github.com/mmcloughlin/avo/gotypes" "github.com/mmcloughlin/avo/operand" "github.com/mmcloughlin/avo/reg" - - "github.com/mmcloughlin/avo/gotypes" ) //go:generate avogen -output zmov.go mov diff --git a/buildtags/buildtags.go b/buildtags/buildtags.go index 8fd61e1..457c38e 100644 --- a/buildtags/buildtags.go +++ b/buildtags/buildtags.go @@ -209,7 +209,7 @@ func (o Option) ToOption() Option { return o } func (o Option) Validate() error { for _, t := range o { if err := t.Validate(); err != nil { - return fmt.Errorf("invalid term \"%s\": %s", t, err) + return fmt.Errorf("invalid term %q: %w", t, err) } } return nil diff --git a/gotypes/components.go b/gotypes/components.go index e9cfdb1..7ae15e3 100644 --- a/gotypes/components.go +++ b/gotypes/components.go @@ -7,9 +7,8 @@ import ( "go/types" "strconv" - "github.com/mmcloughlin/avo/reg" - "github.com/mmcloughlin/avo/operand" + "github.com/mmcloughlin/avo/reg" ) // Sizes provides type sizes used by the standard Go compiler on amd64. @@ -31,7 +30,6 @@ type Component interface { // during any previous calls to Component methods, they will be returned at // resolution time. Resolve() (*Basic, error) - Dereference(r reg.Register) Component // dereference a pointer Base() Component // base pointer of a string or slice Len() Component // length of a string or slice diff --git a/gotypes/components_test.go b/gotypes/components_test.go index 2a045e0..2de7491 100644 --- a/gotypes/components_test.go +++ b/gotypes/components_test.go @@ -1,14 +1,14 @@ package gotypes import ( + "errors" "go/token" "go/types" "strings" "testing" - "github.com/mmcloughlin/avo/reg" - "github.com/mmcloughlin/avo/operand" + "github.com/mmcloughlin/avo/reg" ) func TestBasicKindsArePrimitive(t *testing.T) { @@ -39,6 +39,7 @@ func TestPointersArePrimitive(t *testing.T) { } func AssertPrimitive(t *testing.T, typ types.Type) { + t.Helper() c := NewComponent(typ, operand.NewParamAddr("primitive", 0)) if _, err := c.Resolve(); err != nil { t.Errorf("expected type %s to be primitive: got error '%s'", typ, err) @@ -92,7 +93,7 @@ func TestComponentErrorChaining(t *testing.T) { } for _, c := range cases { _, err := c.Resolve() - if err != expect { + if !errors.Is(err, expect) { t.Fatal("chaining should preserve error") } } diff --git a/internal/cmd/avogen/main.go b/internal/cmd/avogen/main.go index 862f5bd..0147709 100644 --- a/internal/cmd/avogen/main.go +++ b/internal/cmd/avogen/main.go @@ -3,6 +3,7 @@ package main import ( "flag" + "fmt" "go/build" "log" "os" @@ -43,12 +44,17 @@ func main() { log.SetPrefix("avogen: ") log.SetFlags(0) flag.Parse() + if err := run(); err != nil { + log.Fatal(err) + } +} +func run() error { // Build generator. t := flag.Arg(0) builder := generators[t] if builder == nil { - log.Fatalf("unknown generator type '%s'", t) + return fmt.Errorf("unknown generator type '%s'", t) } g := builder(printer.NewArgvConfig()) @@ -58,7 +64,7 @@ func main() { if *output != "" { f, err := os.Create(*output) if err != nil { - log.Fatal(err) + return err } defer f.Close() w = f @@ -71,7 +77,7 @@ func main() { l := load.NewLoaderFromDataDir(*datadir) r, err := l.Load() if err != nil { - log.Fatal(err) + return err } is = r } @@ -81,10 +87,12 @@ func main() { // Write. if _, err := w.Write(b); err != nil { - log.Fatal(err) + return err } if generr != nil { - log.Fatal(generr) + return generr } + + return nil } diff --git a/internal/gen/api.go b/internal/gen/api.go index a7e5f75..43e9605 100644 --- a/internal/gen/api.go +++ b/internal/gen/api.go @@ -187,11 +187,17 @@ func (t *Table) SuffixesTypeName() string { // SuffixesConst returns the constant for a list of suffixes. Suffixes is a // generated array type, so the list is a value not slice type. func (t *Table) SuffixesConst(suffixes inst.Suffixes) string { + return t.SuffixesTypeName() + t.SuffixesList(suffixes) +} + +// SuffixesList returns the constant literal for a list of suffixes, type name +// not included. Use SuffxesConst if the type is required. +func (t *Table) SuffixesList(suffixes inst.Suffixes) string { var parts []string for _, suffix := range suffixes { parts = append(parts, t.SuffixConst(suffix)) } - return t.SuffixesTypeName() + "{" + strings.Join(parts, ", ") + "}" + return "{" + strings.Join(parts, ", ") + "}" } // SuffixesClass returns the enumeration representing all suffixes classes. diff --git a/internal/gen/ctorstest.go b/internal/gen/ctorstest.go index 85860b6..a3832c9 100644 --- a/internal/gen/ctorstest.go +++ b/internal/gen/ctorstest.go @@ -6,10 +6,9 @@ import ( "strings" "github.com/mmcloughlin/avo/internal/api" + "github.com/mmcloughlin/avo/internal/inst" "github.com/mmcloughlin/avo/internal/prnt" "github.com/mmcloughlin/avo/printer" - - "github.com/mmcloughlin/avo/internal/inst" ) type ctorstest struct { diff --git a/internal/gen/optab.go b/internal/gen/optab.go index cda73de..ca51c33 100644 --- a/internal/gen/optab.go +++ b/internal/gen/optab.go @@ -134,7 +134,7 @@ func (t *optab) suffixesType(is []inst.Instruction) { var entries []string for _, class := range inst.SuffixesClasses(is) { for _, suffixes := range class { - entry := fmt.Sprintf("%s: %#v", t.table.SuffixesConst(suffixes), suffixes.Strings()) + entry := fmt.Sprintf("%s: %s", t.table.SuffixesList(suffixes), stringsliteral(suffixes.Strings())) entries = append(entries, entry) } } @@ -177,7 +177,7 @@ func (t *optab) isasEnum(is []inst.Instruction) { // Mapping method to produce the list of ISAs. lists := map[string]string{} for _, isas := range inst.ISACombinations(is) { - lists[api.ISAsIdentifier(isas)] = fmt.Sprintf("%#v", isas) + lists[api.ISAsIdentifier(isas)] = stringsliteral(isas) } t.mapping(e, "List", "[]string", "nil", lists) } @@ -286,3 +286,14 @@ func (t *optab) stringmethod(e *Enum) { } t.mapping(e, "String", "string", `""`, s) } + +func stringsliteral(ss []string) string { + if ss == nil { + return "nil" + } + var quoted []string + for _, s := range ss { + quoted = append(quoted, strconv.Quote(s)) + } + return "{" + strings.Join(quoted, ", ") + "}" +} diff --git a/internal/load/load.go b/internal/load/load.go index 7170d87..ae684d6 100644 --- a/internal/load/load.go +++ b/internal/load/load.go @@ -855,7 +855,7 @@ func dedupe(fs []inst.Form) []inst.Form { return uniq } -// sortforms sorts a list of forms +// sortforms sorts a list of forms. func sortforms(fs []inst.Form) { sort.Slice(fs, func(i, j int) bool { return sortkey(fs[i]) < sortkey(fs[j]) diff --git a/internal/test/utils.go b/internal/test/utils.go index 1e0d929..ebd98f8 100644 --- a/internal/test/utils.go +++ b/internal/test/utils.go @@ -32,7 +32,7 @@ func Assembles(t *testing.T, asm []byte) { defer clean() asmfilename := filepath.Join(dir, "asm.s") - if err := ioutil.WriteFile(asmfilename, asm, 0600); err != nil { + if err := ioutil.WriteFile(asmfilename, asm, 0o600); err != nil { t.Fatal(err) } @@ -96,11 +96,13 @@ func GoTool() string { // goexec runs a "go" command and checks the output. func goexec(t *testing.T, arg ...string) { + t.Helper() Exec(t, GoTool(), arg...) } // Logger builds a logger that writes to the test object. func Logger(tb testing.TB) *log.Logger { + tb.Helper() return log.New(Writer(tb), "test", log.LstdFlags) } @@ -110,6 +112,7 @@ type writer struct { // Writer builds a writer that logs all writes to the test object. func Writer(tb testing.TB) io.Writer { + tb.Helper() return writer{tb} } diff --git a/ir/ir.go b/ir/ir.go index 74b2034..871d488 100644 --- a/ir/ir.go +++ b/ir/ir.go @@ -298,7 +298,7 @@ func (d Datum) Interval() (int, int) { return d.Offset, d.Offset + d.Value.Bytes() } -// Overlaps returns true +// Overlaps returns whether d overlaps with other. func (d Datum) Overlaps(other Datum) bool { s, e := d.Interval() so, eo := other.Interval() diff --git a/ir/ir_test.go b/ir/ir_test.go index a56a843..f37e5ec 100644 --- a/ir/ir_test.go +++ b/ir/ir_test.go @@ -5,7 +5,6 @@ import ( "testing" "github.com/mmcloughlin/avo/operand" - "github.com/mmcloughlin/avo/reg" ) diff --git a/pass/cfg_test.go b/pass/cfg_test.go index e7a2bb1..42ffed7 100644 --- a/pass/cfg_test.go +++ b/pass/cfg_test.go @@ -257,14 +257,17 @@ func ComputeCFG(t *testing.T, f *ir.Function) error { } func AssertSuccessors(t *testing.T, f *ir.Function, expect map[string][]string) { + t.Helper() AssertEqual(t, "successors", OpcodeSuccessorGraph(f), expect) } func AssertPredecessors(t *testing.T, f *ir.Function, expect map[string][]string) { + t.Helper() AssertEqual(t, "predecessors", OpcodePredecessorGraph(f), expect) } func AssertEqual(t *testing.T, what string, got, expect interface{}) { + t.Helper() t.Logf("%s=%#v\n", what, got) if reflect.DeepEqual(expect, got) { return diff --git a/pass/reg_test.go b/pass/reg_test.go index a575f17..5c6b9c0 100644 --- a/pass/reg_test.go +++ b/pass/reg_test.go @@ -83,6 +83,7 @@ func TestLivenessBasic(t *testing.T) { } func AssertLiveness(t *testing.T, ctx *build.Context, in, out [][]reg.Register) { + t.Helper() fn := ConstructLiveness(t, ctx) is := fn.Instructions() @@ -97,12 +98,14 @@ func AssertLiveness(t *testing.T, ctx *build.Context, in, out [][]reg.Register) } func AssertRegistersMatchSet(t *testing.T, rs []reg.Register, s reg.MaskSet) { + t.Helper() if !s.Equals(reg.NewMaskSetFromRegisters(rs)) { t.Fatalf("register slice does not match set: %#v and %#v", rs, s) } } func ConstructLiveness(t *testing.T, ctx *build.Context) *ir.Function { + t.Helper() return BuildFunction(t, ctx, pass.LabelTarget, pass.CFG, pass.Liveness) } diff --git a/reg/x86.go b/reg/x86.go index 1cf68d1..ee7d1c7 100644 --- a/reg/x86.go +++ b/reg/x86.go @@ -100,19 +100,19 @@ func gp(s Spec, id Index, name string, flags ...Info) GPPhysical { // General purpose registers. var ( - // Low byte + // Low byte. AL = gp(S8L, 0, "AL") CL = gp(S8L, 1, "CL") DL = gp(S8L, 2, "DL") BL = gp(S8L, 3, "BL") - // High byte + // High byte. AH = gp(S8H, 0, "AH") CH = gp(S8H, 1, "CH") DH = gp(S8H, 2, "DH") BH = gp(S8H, 3, "BH") - // 8-bit + // 8-bit. SPB = gp(S8, 4, "SP", Restricted) BPB = gp(S8, 5, "BP", BasePointer) SIB = gp(S8, 6, "SI") @@ -126,7 +126,7 @@ var ( R14B = gp(S8, 14, "R14") R15B = gp(S8, 15, "R15") - // 16-bit + // 16-bit. AX = gp(S16, 0, "AX") CX = gp(S16, 1, "CX") DX = gp(S16, 2, "DX") @@ -144,7 +144,7 @@ var ( R14W = gp(S16, 14, "R14") R15W = gp(S16, 15, "R15") - // 32-bit + // 32-bit. EAX = gp(S32, 0, "AX") ECX = gp(S32, 1, "CX") EDX = gp(S32, 2, "DX") @@ -162,7 +162,7 @@ var ( R14L = gp(S32, 14, "R14") R15L = gp(S32, 15, "R15") - // 64-bit + // 64-bit. RAX = gp(S64, 0, "AX") RCX = gp(S64, 1, "CX") RDX = gp(S64, 2, "DX") @@ -230,7 +230,7 @@ func vec(s Spec, id Index, name string, flags ...Info) VecPhysical { // Vector registers. var ( - // 128-bit + // 128-bit. X0 = vec(S128, 0, "X0") X1 = vec(S128, 1, "X1") X2 = vec(S128, 2, "X2") @@ -264,7 +264,7 @@ var ( X30 = vec(S128, 30, "X30") X31 = vec(S128, 31, "X31") - // 256-bit + // 256-bit. Y0 = vec(S256, 0, "Y0") Y1 = vec(S256, 1, "Y1") Y2 = vec(S256, 2, "Y2") @@ -298,7 +298,7 @@ var ( Y30 = vec(S256, 30, "Y30") Y31 = vec(S256, 31, "Y31") - // 512-bit + // 512-bit. Z0 = vec(S512, 0, "Z0") Z1 = vec(S512, 1, "Z1") Z2 = vec(S512, 2, "Z2") diff --git a/script/bootstrap b/script/bootstrap index 2655c54..747d30e 100755 --- a/script/bootstrap +++ b/script/bootstrap @@ -4,7 +4,7 @@ go install ./internal/cmd/asmvet # Install golangci-lint -golangci_lint_version='v1.23.6' +golangci_lint_version='v1.45.2' golangci_install_script="https://raw.githubusercontent.com/golangci/golangci-lint/${golangci_lint_version}/install.sh" curl -sfL "${golangci_install_script}" | sh -s -- -b "$GOPATH/bin" "${golangci_lint_version}" @@ -17,5 +17,8 @@ go install github.com/dlespiau/covertool@v0.0.0-20180314162135-b0c4c6d0583a # asmfmt for enforcing assembly style go install github.com/klauspost/asmfmt/cmd/asmfmt@v1.3.1 -# gofumports for stricter formatting -go install mvdan.cc/gofumpt/gofumports@v0.0.0-20200412215918-a91da47f375c +# goimports for import grouping. +go install golang.org/x/tools/cmd/goimports@v0.1.10 + +# gofumpt for stricter formatting. +go install mvdan.cc/gofumpt@v0.2.1 diff --git a/script/fmt b/script/fmt index 80ff752..4a691f2 100755 --- a/script/fmt +++ b/script/fmt @@ -8,8 +8,11 @@ files=$(find . -name '*.go' -not -path '*/stadtx/*') # Remove blank lines in import blocks. This will force formatting to group # imports correctly. -sed -i.fmtbackup '/^import (/,/)/ { /^$$/ d; }' ${files} +sed -i.fmtbackup '/^import (/,/)/ { /^[ \t]*$/ d; }' ${files} find . -name '*.fmtbackup' -delete -# gofumports is goimports with stricter formatting. -gofumports -w -local ${repo} ${files} +# goimports for import grouping. +goimports -w -local "${repo}" ${files} + +# gofumpt for stricter gofmt-compatible format. +gofumpt -w ${files} diff --git a/x86/inst_test.go b/x86/inst_test.go index c35297e..fb5b0f4 100644 --- a/x86/inst_test.go +++ b/x86/inst_test.go @@ -90,6 +90,7 @@ func TestCases(t *testing.T) { } func MustInstruction(t *testing.T) func(*ir.Instruction, error) *ir.Instruction { + t.Helper() return func(i *ir.Instruction, err error) *ir.Instruction { t.Helper() if err != nil { diff --git a/x86/zoptab.go b/x86/zoptab.go index 4479d4f..bbea9c4 100644 --- a/x86/zoptab.go +++ b/x86/zoptab.go @@ -215,20 +215,20 @@ func (s sffxs) Strings() []string { } var sffxsstringsmap = map[sffxs][]string{ - sffxs{sffxBCST, sffxZ}: []string{"BCST", "Z"}, - sffxs{sffxBCST}: []string{"BCST"}, - sffxs{sffxRD_SAE, sffxZ}: []string{"RD_SAE", "Z"}, - sffxs{sffxRD_SAE}: []string{"RD_SAE"}, - sffxs{sffxRN_SAE, sffxZ}: []string{"RN_SAE", "Z"}, - sffxs{sffxRN_SAE}: []string{"RN_SAE"}, - sffxs{sffxRU_SAE, sffxZ}: []string{"RU_SAE", "Z"}, - sffxs{sffxRU_SAE}: []string{"RU_SAE"}, - sffxs{sffxRZ_SAE, sffxZ}: []string{"RZ_SAE", "Z"}, - sffxs{sffxRZ_SAE}: []string{"RZ_SAE"}, - sffxs{sffxSAE, sffxZ}: []string{"SAE", "Z"}, - sffxs{sffxSAE}: []string{"SAE"}, - sffxs{sffxZ}: []string{"Z"}, - sffxs{}: []string(nil), + {sffxBCST, sffxZ}: {"BCST", "Z"}, + {sffxBCST}: {"BCST"}, + {sffxRD_SAE, sffxZ}: {"RD_SAE", "Z"}, + {sffxRD_SAE}: {"RD_SAE"}, + {sffxRN_SAE, sffxZ}: {"RN_SAE", "Z"}, + {sffxRN_SAE}: {"RN_SAE"}, + {sffxRU_SAE, sffxZ}: {"RU_SAE", "Z"}, + {sffxRU_SAE}: {"RU_SAE"}, + {sffxRZ_SAE, sffxZ}: {"RZ_SAE", "Z"}, + {sffxRZ_SAE}: {"RZ_SAE"}, + {sffxSAE, sffxZ}: {"SAE", "Z"}, + {sffxSAE}: {"SAE"}, + {sffxZ}: {"Z"}, + {}: nil, } type sffxscls uint8 @@ -327,54 +327,54 @@ func (i isas) List() []string { } var isaslisttable = [][]string{ - []string(nil), - []string{"ADX"}, - []string{"SSE2"}, - []string{"SSE"}, - []string{"SSE3"}, - []string{"AES"}, - []string{"BMI"}, - []string{"SSE4.1"}, - []string{"BMI2"}, - []string{"CLFLUSH"}, - []string{"CLFLUSHOPT"}, - []string{"CMOV"}, - []string{"CPUID"}, - []string{"SSE4.2"}, - []string{"AVX512DQ"}, - []string{"AVX512BW"}, - []string{"AVX512F"}, - []string{"LZCNT"}, - []string{"MONITOR"}, - []string{"MOVBE"}, - []string{"SSSE3"}, - []string{"PCLMULQDQ"}, - []string{"POPCNT"}, - []string{"MMX+"}, - []string{"RDRAND"}, - []string{"RDSEED"}, - []string{"RDTSC"}, - []string{"RDTSCP"}, - []string{"SHA"}, - []string{"AVX"}, - []string{"AVX512F", "AVX512VL"}, - []string{"AES", "AVX"}, - []string{"AVX512DQ", "AVX512VL"}, - []string{"AVX2"}, - []string{"F16C"}, - []string{"AVX512VL"}, - []string{"AVX512BW", "AVX512VL"}, - []string{"AVX512ER"}, - []string{"FMA3"}, - []string{"AVX512CD", "AVX512VL"}, - []string{"AVX512CD"}, - []string{"AVX", "PCLMULQDQ"}, - []string{"AVX512VBMI", "AVX512VL"}, - []string{"AVX512VBMI"}, - []string{"AVX512IFMA", "AVX512VL"}, - []string{"AVX512IFMA"}, - []string{"AVX512VPOPCNTDQ"}, - []string{"AVX512BW", "AVX512F"}, + nil, + {"ADX"}, + {"SSE2"}, + {"SSE"}, + {"SSE3"}, + {"AES"}, + {"BMI"}, + {"SSE4.1"}, + {"BMI2"}, + {"CLFLUSH"}, + {"CLFLUSHOPT"}, + {"CMOV"}, + {"CPUID"}, + {"SSE4.2"}, + {"AVX512DQ"}, + {"AVX512BW"}, + {"AVX512F"}, + {"LZCNT"}, + {"MONITOR"}, + {"MOVBE"}, + {"SSSE3"}, + {"PCLMULQDQ"}, + {"POPCNT"}, + {"MMX+"}, + {"RDRAND"}, + {"RDSEED"}, + {"RDTSC"}, + {"RDTSCP"}, + {"SHA"}, + {"AVX"}, + {"AVX512F", "AVX512VL"}, + {"AES", "AVX"}, + {"AVX512DQ", "AVX512VL"}, + {"AVX2"}, + {"F16C"}, + {"AVX512VL"}, + {"AVX512BW", "AVX512VL"}, + {"AVX512ER"}, + {"FMA3"}, + {"AVX512CD", "AVX512VL"}, + {"AVX512CD"}, + {"AVX", "PCLMULQDQ"}, + {"AVX512VBMI", "AVX512VL"}, + {"AVX512VBMI"}, + {"AVX512IFMA", "AVX512VL"}, + {"AVX512IFMA"}, + {"AVX512VPOPCNTDQ"}, + {"AVX512BW", "AVX512F"}, } type opc uint16