Files
wehub-resource-sync c4536f7e05
CI / test (push) Failing after 1s
CI / macOS amd64 (push) Has been cancelled
CI / macOS arm64 (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:30:31 +08:00

95 lines
3.1 KiB
Go

// Package asmref holds a generated, flattened instruction reference used for
// hover tooltips. The table is produced by ./gen from CPU ISA XML (ARM's
// official AArch64 release and the uops.info XED-derived dump) and embedded as
// gzip-compressed JSON — see README.md for how to regenerate.
//
// asmref is deliberately just reference text (brief, description, syntax,
// operand meanings) plus x86 performance data. The bespoke Go-pseudocode
// effects live in internal/asmhelp; nothing here overwrites them.
package asmref
import (
"bytes"
"compress/gzip"
_ "embed"
"encoding/json"
"io"
"strings"
"sync"
)
// Entry is the flattened reference for a single mnemonic. It matches the JSON
// schema written by the generator; both gen and runtime share this type.
type Entry struct {
Brief string `json:"brief,omitempty"`
Description string `json:"description,omitempty"`
Syntax []string `json:"syntax,omitempty"`
Operands map[string]string `json:"operands,omitempty"`
// Variants holds x86 per-operand-form performance data across all measured
// microarchitectures. Empty for ARM.
Variants []Variant `json:"variants,omitempty"`
}
// Variant is one x86 operand form (e.g. "ADD (R32, R32)") and its measured
// performance on each microarchitecture.
type Variant struct {
Form string `json:"form"`
Perf []ArchPerf `json:"perf,omitempty"`
}
// ArchPerf is the uops.info measurement for one microarchitecture.
type ArchPerf struct {
Arch string `json:"arch"`
Uops int `json:"uops,omitempty"`
Ports string `json:"ports,omitempty"` // uops.info notation, e.g. "1*p0156"
Latency int `json:"lat,omitempty"` // worst-case cycles across operand pairs
TP float64 `json:"tp,omitempty"` // throughput (cycles per instruction)
}
// PerfFor returns the per-variant measurements for one microarchitecture.
func (e Entry) PerfFor(arch string) []ArchPerf {
var out []ArchPerf
for _, v := range e.Variants {
for _, p := range v.Perf {
if p.Arch == arch {
out = append(out, p)
}
}
}
return out
}
// Regenerating needs the real ISA dumps under data/ (run data/download.sh
// first). The ARM directory name tracks the pinned release; bump both here and
// in data/download.sh when updating.
//go:generate go run ./gen -arm ../../data/arm64/ISA_A64_xml_A_profile-2025-12 -x86 ../../data/x86/instructions.xml -out table.json.gz
//go:embed table.json.gz
var tableGz []byte
var (
tableOnce sync.Once
table map[string]Entry
)
func load() {
// A malformed embed should surface as "no data" rather than panic in the
// UI hover path; the generator is what guarantees validity.
if r, err := gzip.NewReader(bytes.NewReader(tableGz)); err == nil {
if data, err := io.ReadAll(r); err == nil {
_ = json.Unmarshal(data, &table)
}
}
if table == nil {
table = map[string]Entry{}
}
}
// Lookup returns the reference entry for a mnemonic (case-insensitive). The
// table is loaded once on first use.
func Lookup(mnemonic string) (Entry, bool) {
tableOnce.Do(load)
e, ok := table[strings.ToUpper(strings.TrimSpace(mnemonic))]
return e, ok
}