Compare commits
4
Commits
95025be1bc
...
53de91b2df
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53de91b2df | ||
|
|
8a36af7c7d | ||
|
|
e9789ce3f4 | ||
|
|
837231c068 |
@@ -9,6 +9,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
- **Per-architecture reference pages.** [docs/asm/](docs/asm/README.md)
|
||||||
|
gains AMD64, ARM64, RISCV64 and LOONG64: the register files and the
|
||||||
|
roles the ABI fixes, addressing, operand order with every special form,
|
||||||
|
constants and materialisation, alignment, fences and the relocations
|
||||||
|
each target emits. An instruction inventory appendix per architecture
|
||||||
|
is generated from the toolchain's own tables by `just gen`, and the
|
||||||
|
regenerated tables recognise 147 more mnemonics than the previous
|
||||||
|
release carried (arm64 107, riscv64 31, loong64 9).
|
||||||
|
- **The Plan 9 assembly language reference.** [docs/asm/](docs/asm/README.md)
|
||||||
|
opens the complete language reference with its common core: the lexicon,
|
||||||
|
statement structure and constant expressions, the operand grammar with
|
||||||
|
the pseudo-registers and symbol naming, the directives and the function
|
||||||
|
flag vocabulary, preprocessing with `#define` and `#include`, and the
|
||||||
|
Go-embedded layer (ABI0, prototypes, `go_asm.h`, `funcdata.h` and the
|
||||||
|
runtime contract). Every claim is verified against `go tool asm` of
|
||||||
|
Go 1.27.1 and gasm's differential tests; the per-architecture pages and
|
||||||
|
generated instruction appendices follow.
|
||||||
- **GOOBJ format specification.** [docs/GOOBJ.md](docs/GOOBJ.md)
|
- **GOOBJ format specification.** [docs/GOOBJ.md](docs/GOOBJ.md)
|
||||||
documents the Go object file format in full: both containers, the 96
|
documents the Go object file format in full: both containers, the 96
|
||||||
byte header and all 19 blocks, every structure with its byte
|
byte header and all 19 blocks, every structure with its byte
|
||||||
|
|||||||
@@ -186,8 +186,9 @@ verified the way the code is verified: an encoding documented here is
|
|||||||
one that differential tests against `go tool asm` confirm
|
one that differential tests against `go tool asm` confirm
|
||||||
byte-for-byte, and a format field documented here is one the linker
|
byte-for-byte, and a format field documented here is one the linker
|
||||||
demonstrably reads. The work has begun: [docs/GOOBJ.md](docs/GOOBJ.md)
|
demonstrably reads. The work has begun: [docs/GOOBJ.md](docs/GOOBJ.md)
|
||||||
specifies the object file format completely. The assembler language
|
specifies the object file format completely, and
|
||||||
reference follows.
|
[docs/asm/README.md](docs/asm/README.md) opens the language reference
|
||||||
|
with its common core. The per-architecture pages follow.
|
||||||
|
|
||||||
## Direction
|
## Direction
|
||||||
|
|
||||||
@@ -315,6 +316,7 @@ recipe.
|
|||||||
them
|
them
|
||||||
- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md): components and data flow
|
- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md): components and data flow
|
||||||
- [docs/GOOBJ.md](docs/GOOBJ.md): the GOOBJ object file format specification
|
- [docs/GOOBJ.md](docs/GOOBJ.md): the GOOBJ object file format specification
|
||||||
|
- [docs/asm/](docs/asm/README.md): the Plan 9 assembly language reference
|
||||||
- [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md): development setup and recipes
|
- [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md): development setup and recipes
|
||||||
- [CHANGELOG.md](CHANGELOG.md): release history
|
- [CHANGELOG.md](CHANGELOG.md): release history
|
||||||
|
|
||||||
|
|||||||
+101
-3
@@ -8,6 +8,10 @@
|
|||||||
// names so gasm-devkit supports every instruction the real assembler does,
|
// names so gasm-devkit supports every instruction the real assembler does,
|
||||||
// with no hand-maintained (and therefore inevitably incomplete) lists.
|
// with no hand-maintained (and therefore inevitably incomplete) lists.
|
||||||
//
|
//
|
||||||
|
// The same data feeds the generated instruction appendices of the assembly
|
||||||
|
// language reference, docs/asm/INSTRUCTIONS-<ARCH>.md, so that the reference
|
||||||
|
// cannot drift from the tables it documents.
|
||||||
|
//
|
||||||
// Usage (via the justfile):
|
// Usage (via the justfile):
|
||||||
//
|
//
|
||||||
// just gen
|
// just gen
|
||||||
@@ -26,6 +30,9 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"sourcedock.dev/petrbalvin/gasm-devkit/arch"
|
||||||
|
"sourcedock.dev/petrbalvin/gasm-devkit/asm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// archDirs maps a gasm-devkit architecture name to its obj sub-directory.
|
// archDirs maps a gasm-devkit architecture name to its obj sub-directory.
|
||||||
@@ -39,11 +46,30 @@ var archDirs = []struct {
|
|||||||
{"loong64", "loong64"},
|
{"loong64", "loong64"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// docPages maps an architecture to its generated appendix in the language
|
||||||
|
// reference. The amd64 page carries a per-mnemonic encodability column,
|
||||||
|
// decided by asm.Encodable, which mirrors the encoder's own dispatch; the
|
||||||
|
// other targets have no single cheap predicate, so their pages carry the
|
||||||
|
// inventory and point at the live measurement instead.
|
||||||
|
var docPages = []struct {
|
||||||
|
arch arch.Arch
|
||||||
|
title string
|
||||||
|
file string
|
||||||
|
anames string
|
||||||
|
encodable bool
|
||||||
|
}{
|
||||||
|
{arch.AMD64, "AMD64", "INSTRUCTIONS-AMD64.md", "cmd/internal/obj/x86/anames.go", true},
|
||||||
|
{arch.ARM64, "ARM64", "INSTRUCTIONS-ARM64.md", "cmd/internal/obj/arm64/anames.go", false},
|
||||||
|
{arch.RISCV, "RISC-V 64", "INSTRUCTIONS-RISCV64.md", "cmd/internal/obj/riscv/anames.go", false},
|
||||||
|
{arch.LOONG64, "LoongArch 64", "INSTRUCTIONS-LOONG64.md", "cmd/internal/obj/loong64/anames.go", false},
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
goroot := strings.TrimSpace(runGoEnvGOROOT())
|
goroot := strings.TrimSpace(runGoEnvGOROOT())
|
||||||
if goroot == "" {
|
if goroot == "" {
|
||||||
fatal("could not determine GOROOT")
|
fatal("could not determine GOROOT")
|
||||||
}
|
}
|
||||||
|
version := strings.TrimSpace(runGoEnv("GOVERSION"))
|
||||||
// The common opcodes shared by every architecture (RET, JMP, NOP, CALL,
|
// The common opcodes shared by every architecture (RET, JMP, NOP, CALL,
|
||||||
// TEXT, FUNCDATA, …) live in cmd/internal/obj/util.go.
|
// TEXT, FUNCDATA, …) live in cmd/internal/obj/util.go.
|
||||||
commonPath := filepath.Join(goroot, "src", "cmd", "internal", "obj", "util.go")
|
commonPath := filepath.Join(goroot, "src", "cmd", "internal", "obj", "util.go")
|
||||||
@@ -57,16 +83,24 @@ func main() {
|
|||||||
}
|
}
|
||||||
fmt.Printf("%-8s %4d instructions -> arch/common_gen.go\n", "common", len(common))
|
fmt.Printf("%-8s %4d instructions -> arch/common_gen.go\n", "common", len(common))
|
||||||
|
|
||||||
|
names := map[string][]string{}
|
||||||
for _, a := range archDirs {
|
for _, a := range archDirs {
|
||||||
path := filepath.Join(goroot, "src", "cmd", "internal", "obj", a.sub, "anames.go")
|
path := filepath.Join(goroot, "src", "cmd", "internal", "obj", a.sub, "anames.go")
|
||||||
names, err := extractInstrs(path)
|
names[a.arch], err = extractInstrs(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fatal("extract %s: %v", a.arch, err)
|
fatal("extract %s: %v", a.arch, err)
|
||||||
}
|
}
|
||||||
if err := writeGen(a.arch, a.sub, names); err != nil {
|
if err := writeGen(a.arch, a.sub, names[a.arch]); err != nil {
|
||||||
fatal("write %s: %v", a.arch, err)
|
fatal("write %s: %v", a.arch, err)
|
||||||
}
|
}
|
||||||
fmt.Printf("%-8s %4d instructions -> arch/%s_gen.go\n", a.arch, len(names), a.arch)
|
fmt.Printf("%-8s %4d instructions -> arch/%s_gen.go\n", a.arch, len(names[a.arch]), a.arch)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range docPages {
|
||||||
|
if err := writeDocPage(p.arch, p.title, p.file, p.anames, version, p.encodable); err != nil {
|
||||||
|
fatal("write %s: %v", p.file, err)
|
||||||
|
}
|
||||||
|
fmt.Printf("%-8s -> docs/asm/%s\n", p.arch, p.file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,6 +206,61 @@ func writeGen(arch, sub string, names []string) error {
|
|||||||
return os.WriteFile(filepath.Join("arch", arch+"_gen.go"), []byte(b.String()), 0o644)
|
return os.WriteFile(filepath.Join("arch", arch+"_gen.go"), []byte(b.String()), 0o644)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// writeDocPage emits docs/asm/<file>, the generated instruction appendix of
|
||||||
|
// the language reference for one architecture: every mnemonic the toolchain
|
||||||
|
// accepts, with the curated summary where the architecture table carries one
|
||||||
|
// and, on amd64, a per-mnemonic encodability column.
|
||||||
|
func writeDocPage(a arch.Arch, title, file, anames, version string, encodable bool) error {
|
||||||
|
table := arch.ForArch(a)
|
||||||
|
instrs := table.Instructions()
|
||||||
|
|
||||||
|
var b strings.Builder
|
||||||
|
b.WriteString("# " + title + ": instruction inventory\n\n")
|
||||||
|
b.WriteString("Generated by gasm-devkit's `_gen` from the Go toolchain's instruction table\n")
|
||||||
|
b.WriteString("(`" + anames + "`, " + version + "); DO NOT EDIT. This page lists every mnemonic\n")
|
||||||
|
b.WriteString("`go tool asm` accepts on this target, which is the upper bound of the\n")
|
||||||
|
b.WriteString("language on it: a name absent here is not an instruction of the target,\n")
|
||||||
|
b.WriteString("and a name present here may still be one gasm's encoder cannot emit yet.\n\n")
|
||||||
|
|
||||||
|
encodableCount := 0
|
||||||
|
if encodable {
|
||||||
|
b.WriteString("The `gasm encodes` column reports whether gasm's encoder can emit the\n")
|
||||||
|
b.WriteString("mnemonic today; the gap is the encoder backlog, measured live by\n")
|
||||||
|
b.WriteString("`gasm audit-instructions`.\n\n")
|
||||||
|
b.WriteString("| Mnemonic | gasm encodes | Notes |\n")
|
||||||
|
b.WriteString("|---|---|---|\n")
|
||||||
|
for _, in := range instrs {
|
||||||
|
ok := asm.Encodable(in.Name)
|
||||||
|
if ok {
|
||||||
|
encodableCount++
|
||||||
|
}
|
||||||
|
b.WriteString("| `" + in.Name + "` | " + yesNo(ok) + " | " + in.Summary + " |\n")
|
||||||
|
}
|
||||||
|
b.WriteString("\n")
|
||||||
|
fmt.Fprintf(&b, "Recognised: %d mnemonics. gasm encodes: %d.\n", len(instrs), encodableCount)
|
||||||
|
} else {
|
||||||
|
b.WriteString("The inventory carries no per-mnemonic encoder column: on this target\n")
|
||||||
|
b.WriteString("encodability is decided per operand shape, and the live measured\n")
|
||||||
|
b.WriteString("coverage is reported by `gasm audit-instructions`.\n\n")
|
||||||
|
b.WriteString("| Mnemonic | Notes |\n")
|
||||||
|
b.WriteString("|---|---|\n")
|
||||||
|
for _, in := range instrs {
|
||||||
|
b.WriteString("| `" + in.Name + "` | " + in.Summary + " |\n")
|
||||||
|
}
|
||||||
|
b.WriteString("\n")
|
||||||
|
fmt.Fprintf(&b, "Recognised: %d mnemonics.\n", len(instrs))
|
||||||
|
}
|
||||||
|
return os.WriteFile(filepath.Join("docs", "asm", file), []byte(b.String()), 0o644)
|
||||||
|
}
|
||||||
|
|
||||||
|
// yesNo renders a boolean as the word the appendix tables use.
|
||||||
|
func yesNo(v bool) string {
|
||||||
|
if v {
|
||||||
|
return "yes"
|
||||||
|
}
|
||||||
|
return "no"
|
||||||
|
}
|
||||||
|
|
||||||
func runGoEnvGOROOT() string {
|
func runGoEnvGOROOT() string {
|
||||||
out, err := exec.Command("go", "env", "GOROOT").Output()
|
out, err := exec.Command("go", "env", "GOROOT").Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -180,6 +269,15 @@ func runGoEnvGOROOT() string {
|
|||||||
return string(out)
|
return string(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// runGoEnv runs `go env` for a single variable.
|
||||||
|
func runGoEnv(name string) string {
|
||||||
|
out, err := exec.Command("go", "env", name).Output()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return string(out)
|
||||||
|
}
|
||||||
|
|
||||||
func fatal(format string, args ...any) {
|
func fatal(format string, args ...any) {
|
||||||
fmt.Fprintf(os.Stderr, "gen: "+format+"\n", args...)
|
fmt.Fprintf(os.Stderr, "gen: "+format+"\n", args...)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|||||||
@@ -364,6 +364,8 @@ var arm64GeneratedInstrs = []string{
|
|||||||
"REVW",
|
"REVW",
|
||||||
"ROR",
|
"ROR",
|
||||||
"RORW",
|
"RORW",
|
||||||
|
"RPRFM",
|
||||||
|
"SB",
|
||||||
"SBC",
|
"SBC",
|
||||||
"SBCS",
|
"SBCS",
|
||||||
"SBCSW",
|
"SBCSW",
|
||||||
@@ -477,23 +479,68 @@ var arm64GeneratedInstrs = []string{
|
|||||||
"UXTH",
|
"UXTH",
|
||||||
"UXTHW",
|
"UXTHW",
|
||||||
"UXTW",
|
"UXTW",
|
||||||
|
"VABS",
|
||||||
"VADD",
|
"VADD",
|
||||||
"VADDP",
|
"VADDP",
|
||||||
"VADDV",
|
"VADDV",
|
||||||
"VAND",
|
"VAND",
|
||||||
"VBCAX",
|
"VBCAX",
|
||||||
|
"VBIC",
|
||||||
"VBIF",
|
"VBIF",
|
||||||
"VBIT",
|
"VBIT",
|
||||||
"VBSL",
|
"VBSL",
|
||||||
|
"VCLS",
|
||||||
|
"VCLZ",
|
||||||
"VCMEQ",
|
"VCMEQ",
|
||||||
|
"VCMGE",
|
||||||
|
"VCMGT",
|
||||||
|
"VCMHI",
|
||||||
|
"VCMHS",
|
||||||
|
"VCMLE",
|
||||||
|
"VCMLT",
|
||||||
"VCMTST",
|
"VCMTST",
|
||||||
"VCNT",
|
"VCNT",
|
||||||
"VDUP",
|
"VDUP",
|
||||||
"VEOR",
|
"VEOR",
|
||||||
"VEOR3",
|
"VEOR3",
|
||||||
"VEXT",
|
"VEXT",
|
||||||
|
"VFABS",
|
||||||
|
"VFADD",
|
||||||
|
"VFADDP",
|
||||||
|
"VFCMEQ",
|
||||||
|
"VFCMGE",
|
||||||
|
"VFCMGT",
|
||||||
|
"VFCMLE",
|
||||||
|
"VFCMLT",
|
||||||
|
"VFCVTL",
|
||||||
|
"VFCVTL2",
|
||||||
|
"VFCVTN",
|
||||||
|
"VFCVTN2",
|
||||||
|
"VFCVTZS",
|
||||||
|
"VFCVTZU",
|
||||||
|
"VFDIV",
|
||||||
|
"VFMAX",
|
||||||
|
"VFMAXNM",
|
||||||
|
"VFMAXNMP",
|
||||||
|
"VFMAXNMV",
|
||||||
|
"VFMAXP",
|
||||||
|
"VFMAXV",
|
||||||
|
"VFMIN",
|
||||||
|
"VFMINNM",
|
||||||
|
"VFMINNMP",
|
||||||
|
"VFMINNMV",
|
||||||
|
"VFMINP",
|
||||||
|
"VFMINV",
|
||||||
"VFMLA",
|
"VFMLA",
|
||||||
"VFMLS",
|
"VFMLS",
|
||||||
|
"VFMUL",
|
||||||
|
"VFNEG",
|
||||||
|
"VFRINTM",
|
||||||
|
"VFRINTN",
|
||||||
|
"VFRINTP",
|
||||||
|
"VFRINTZ",
|
||||||
|
"VFSQRT",
|
||||||
|
"VFSUB",
|
||||||
"VLD1",
|
"VLD1",
|
||||||
"VLD1R",
|
"VLD1R",
|
||||||
"VLD2",
|
"VLD2",
|
||||||
@@ -502,11 +549,17 @@ var arm64GeneratedInstrs = []string{
|
|||||||
"VLD3R",
|
"VLD3R",
|
||||||
"VLD4",
|
"VLD4",
|
||||||
"VLD4R",
|
"VLD4R",
|
||||||
|
"VMLA",
|
||||||
|
"VMLS",
|
||||||
"VMOV",
|
"VMOV",
|
||||||
"VMOVD",
|
"VMOVD",
|
||||||
"VMOVI",
|
"VMOVI",
|
||||||
"VMOVQ",
|
"VMOVQ",
|
||||||
"VMOVS",
|
"VMOVS",
|
||||||
|
"VMUL",
|
||||||
|
"VNEG",
|
||||||
|
"VNOT",
|
||||||
|
"VORN",
|
||||||
"VORR",
|
"VORR",
|
||||||
"VPMULL",
|
"VPMULL",
|
||||||
"VPMULL2",
|
"VPMULL2",
|
||||||
@@ -515,14 +568,47 @@ var arm64GeneratedInstrs = []string{
|
|||||||
"VREV16",
|
"VREV16",
|
||||||
"VREV32",
|
"VREV32",
|
||||||
"VREV64",
|
"VREV64",
|
||||||
|
"VSCVTF",
|
||||||
|
"VSHADD",
|
||||||
"VSHL",
|
"VSHL",
|
||||||
|
"VSHRN",
|
||||||
|
"VSHRN2",
|
||||||
"VSLI",
|
"VSLI",
|
||||||
|
"VSMAX",
|
||||||
|
"VSMAXP",
|
||||||
|
"VSMAXV",
|
||||||
|
"VSMIN",
|
||||||
|
"VSMINP",
|
||||||
|
"VSMINV",
|
||||||
|
"VSMLAL",
|
||||||
|
"VSMLAL2",
|
||||||
|
"VSMLSL",
|
||||||
|
"VSMLSL2",
|
||||||
|
"VSMULL",
|
||||||
|
"VSMULL2",
|
||||||
|
"VSQABS",
|
||||||
|
"VSQADD",
|
||||||
|
"VSQNEG",
|
||||||
|
"VSQSHL",
|
||||||
|
"VSQSUB",
|
||||||
|
"VSQXTN",
|
||||||
|
"VSQXTN2",
|
||||||
|
"VSQXTUN",
|
||||||
|
"VSQXTUN2",
|
||||||
|
"VSRHADD",
|
||||||
"VSRI",
|
"VSRI",
|
||||||
|
"VSRSHR",
|
||||||
|
"VSSHL",
|
||||||
|
"VSSHLL",
|
||||||
|
"VSSHLL2",
|
||||||
|
"VSSHR",
|
||||||
"VST1",
|
"VST1",
|
||||||
"VST2",
|
"VST2",
|
||||||
"VST3",
|
"VST3",
|
||||||
"VST4",
|
"VST4",
|
||||||
"VSUB",
|
"VSUB",
|
||||||
|
"VSXTL",
|
||||||
|
"VSXTL2",
|
||||||
"VTBL",
|
"VTBL",
|
||||||
"VTBX",
|
"VTBX",
|
||||||
"VTRN1",
|
"VTRN1",
|
||||||
@@ -530,8 +616,27 @@ var arm64GeneratedInstrs = []string{
|
|||||||
"VUADDLV",
|
"VUADDLV",
|
||||||
"VUADDW",
|
"VUADDW",
|
||||||
"VUADDW2",
|
"VUADDW2",
|
||||||
|
"VUCVTF",
|
||||||
|
"VUHADD",
|
||||||
"VUMAX",
|
"VUMAX",
|
||||||
|
"VUMAXP",
|
||||||
|
"VUMAXV",
|
||||||
"VUMIN",
|
"VUMIN",
|
||||||
|
"VUMINP",
|
||||||
|
"VUMINV",
|
||||||
|
"VUMLAL",
|
||||||
|
"VUMLAL2",
|
||||||
|
"VUMLSL",
|
||||||
|
"VUMLSL2",
|
||||||
|
"VUMULL",
|
||||||
|
"VUMULL2",
|
||||||
|
"VUQADD",
|
||||||
|
"VUQSHL",
|
||||||
|
"VUQSUB",
|
||||||
|
"VUQXTN",
|
||||||
|
"VUQXTN2",
|
||||||
|
"VURHADD",
|
||||||
|
"VUSHL",
|
||||||
"VUSHLL",
|
"VUSHLL",
|
||||||
"VUSHLL2",
|
"VUSHLL2",
|
||||||
"VUSHR",
|
"VUSHR",
|
||||||
@@ -541,6 +646,8 @@ var arm64GeneratedInstrs = []string{
|
|||||||
"VUZP1",
|
"VUZP1",
|
||||||
"VUZP2",
|
"VUZP2",
|
||||||
"VXAR",
|
"VXAR",
|
||||||
|
"VXTN",
|
||||||
|
"VXTN2",
|
||||||
"VZIP1",
|
"VZIP1",
|
||||||
"VZIP2",
|
"VZIP2",
|
||||||
"WFE",
|
"WFE",
|
||||||
|
|||||||
@@ -152,6 +152,8 @@ var loong64GeneratedInstrs = []string{
|
|||||||
"FNMADDF",
|
"FNMADDF",
|
||||||
"FNMSUBD",
|
"FNMSUBD",
|
||||||
"FNMSUBF",
|
"FNMSUBF",
|
||||||
|
"FRINTD",
|
||||||
|
"FRINTF",
|
||||||
"FSCALEBD",
|
"FSCALEBD",
|
||||||
"FSCALEBF",
|
"FSCALEBF",
|
||||||
"FSEL",
|
"FSEL",
|
||||||
@@ -177,7 +179,10 @@ var loong64GeneratedInstrs = []string{
|
|||||||
"FTINTWF",
|
"FTINTWF",
|
||||||
"JIRL",
|
"JIRL",
|
||||||
"LL",
|
"LL",
|
||||||
|
"LLACQV",
|
||||||
|
"LLACQW",
|
||||||
"LLV",
|
"LLV",
|
||||||
|
"LLW",
|
||||||
"LU12IW",
|
"LU12IW",
|
||||||
"LU32ID",
|
"LU32ID",
|
||||||
"LU52ID",
|
"LU52ID",
|
||||||
@@ -248,7 +253,11 @@ var loong64GeneratedInstrs = []string{
|
|||||||
"ROTR",
|
"ROTR",
|
||||||
"ROTRV",
|
"ROTRV",
|
||||||
"SC",
|
"SC",
|
||||||
|
"SCQ",
|
||||||
|
"SCRELV",
|
||||||
|
"SCRELW",
|
||||||
"SCV",
|
"SCV",
|
||||||
|
"SCW",
|
||||||
"SGT",
|
"SGT",
|
||||||
"SGTU",
|
"SGTU",
|
||||||
"SLL",
|
"SLL",
|
||||||
|
|||||||
@@ -81,6 +81,9 @@ var riscvGeneratedInstrs = []string{
|
|||||||
"CLD",
|
"CLD",
|
||||||
"CLDSP",
|
"CLDSP",
|
||||||
"CLI",
|
"CLI",
|
||||||
|
"CLMUL",
|
||||||
|
"CLMULH",
|
||||||
|
"CLMULR",
|
||||||
"CLUI",
|
"CLUI",
|
||||||
"CLW",
|
"CLW",
|
||||||
"CLWSP",
|
"CLWSP",
|
||||||
@@ -95,13 +98,20 @@ var riscvGeneratedInstrs = []string{
|
|||||||
"CSDSP",
|
"CSDSP",
|
||||||
"CSLLI",
|
"CSLLI",
|
||||||
"CSRAI",
|
"CSRAI",
|
||||||
|
"CSRC",
|
||||||
|
"CSRCI",
|
||||||
"CSRLI",
|
"CSRLI",
|
||||||
|
"CSRR",
|
||||||
"CSRRC",
|
"CSRRC",
|
||||||
"CSRRCI",
|
"CSRRCI",
|
||||||
"CSRRS",
|
"CSRRS",
|
||||||
"CSRRSI",
|
"CSRRSI",
|
||||||
"CSRRW",
|
"CSRRW",
|
||||||
"CSRRWI",
|
"CSRRWI",
|
||||||
|
"CSRS",
|
||||||
|
"CSRSI",
|
||||||
|
"CSRW",
|
||||||
|
"CSRWI",
|
||||||
"CSUB",
|
"CSUB",
|
||||||
"CSUBW",
|
"CSUBW",
|
||||||
"CSW",
|
"CSW",
|
||||||
@@ -259,6 +269,7 @@ var riscvGeneratedInstrs = []string{
|
|||||||
"ORCB",
|
"ORCB",
|
||||||
"ORI",
|
"ORI",
|
||||||
"ORN",
|
"ORN",
|
||||||
|
"PAUSE",
|
||||||
"RDCYCLE",
|
"RDCYCLE",
|
||||||
"RDINSTRET",
|
"RDINSTRET",
|
||||||
"RDTIME",
|
"RDTIME",
|
||||||
@@ -322,6 +333,8 @@ var riscvGeneratedInstrs = []string{
|
|||||||
"VADDVI",
|
"VADDVI",
|
||||||
"VADDVV",
|
"VADDVV",
|
||||||
"VADDVX",
|
"VADDVX",
|
||||||
|
"VANDNVV",
|
||||||
|
"VANDNVX",
|
||||||
"VANDVI",
|
"VANDVI",
|
||||||
"VANDVV",
|
"VANDVV",
|
||||||
"VANDVX",
|
"VANDVX",
|
||||||
@@ -329,8 +342,17 @@ var riscvGeneratedInstrs = []string{
|
|||||||
"VASUBUVX",
|
"VASUBUVX",
|
||||||
"VASUBVV",
|
"VASUBVV",
|
||||||
"VASUBVX",
|
"VASUBVX",
|
||||||
|
"VBREV8V",
|
||||||
|
"VBREVV",
|
||||||
|
"VCLMULHVV",
|
||||||
|
"VCLMULHVX",
|
||||||
|
"VCLMULVV",
|
||||||
|
"VCLMULVX",
|
||||||
|
"VCLZV",
|
||||||
"VCOMPRESSVM",
|
"VCOMPRESSVM",
|
||||||
"VCPOPM",
|
"VCPOPM",
|
||||||
|
"VCPOPV",
|
||||||
|
"VCTZV",
|
||||||
"VDIVUVV",
|
"VDIVUVV",
|
||||||
"VDIVUVX",
|
"VDIVUVX",
|
||||||
"VDIVVV",
|
"VDIVVV",
|
||||||
@@ -743,10 +765,16 @@ var riscvGeneratedInstrs = []string{
|
|||||||
"VREMUVX",
|
"VREMUVX",
|
||||||
"VREMVV",
|
"VREMVV",
|
||||||
"VREMVX",
|
"VREMVX",
|
||||||
|
"VREV8V",
|
||||||
"VRGATHEREI16VV",
|
"VRGATHEREI16VV",
|
||||||
"VRGATHERVI",
|
"VRGATHERVI",
|
||||||
"VRGATHERVV",
|
"VRGATHERVV",
|
||||||
"VRGATHERVX",
|
"VRGATHERVX",
|
||||||
|
"VROLVV",
|
||||||
|
"VROLVX",
|
||||||
|
"VRORVI",
|
||||||
|
"VRORVV",
|
||||||
|
"VRORVX",
|
||||||
"VRSUBVI",
|
"VRSUBVI",
|
||||||
"VRSUBVX",
|
"VRSUBVX",
|
||||||
"VS1RV",
|
"VS1RV",
|
||||||
@@ -950,6 +978,9 @@ var riscvGeneratedInstrs = []string{
|
|||||||
"VWMULVX",
|
"VWMULVX",
|
||||||
"VWREDSUMUVS",
|
"VWREDSUMUVS",
|
||||||
"VWREDSUMVS",
|
"VWREDSUMVS",
|
||||||
|
"VWSLLVI",
|
||||||
|
"VWSLLVV",
|
||||||
|
"VWSLLVX",
|
||||||
"VWSUBUVV",
|
"VWSUBUVV",
|
||||||
"VWSUBUVX",
|
"VWSUBUVX",
|
||||||
"VWSUBUWV",
|
"VWSUBUWV",
|
||||||
|
|||||||
@@ -0,0 +1,124 @@
|
|||||||
|
# AMD64
|
||||||
|
|
||||||
|
Layer 1, target page. Verified against `go tool asm` of Go 1.27.1 and against
|
||||||
|
gasm's encoder, whose output is compared byte for byte with the toolchain's
|
||||||
|
and executed on real hardware (`gasm verify`). The complete mnemonic
|
||||||
|
inventory lives in the generated appendix
|
||||||
|
[INSTRUCTIONS-AMD64.md](INSTRUCTIONS-AMD64.md); this page is the grammar and
|
||||||
|
the conventions.
|
||||||
|
|
||||||
|
## Registers
|
||||||
|
|
||||||
|
| Group | Names | Notes |
|
||||||
|
|---|---|---|
|
||||||
|
| General purpose, 64-bit | `AX` `BX` `CX` `DX` `SI` `DI` `BP` `SP` `R8` to `R15` | bare names, no prefix |
|
||||||
|
| Sub-registers | `AL` `CL` `DL` `BL` `AH` family; `R8B` `R8W` `R8D` for the byte, word and double word of `R8` | width rides the mnemonic as well |
|
||||||
|
| Vector | `X0` to `X15` (128-bit), `Y0` to `Y15` (256-bit), `Z0` to `Z31` (512-bit) | SSE, AVX and AVX-512 |
|
||||||
|
| Mask | `K0` to `K7` | AVX-512 opmask |
|
||||||
|
| System | `TLS` | the thread pointer, see below |
|
||||||
|
|
||||||
|
Roles the calling convention fixes, which assembly must respect and can rely
|
||||||
|
on:
|
||||||
|
|
||||||
|
- `SP` is the hardware stack pointer; the virtual frame pointer of the
|
||||||
|
common language is the pseudo-register SP of OPERANDS.md, a different
|
||||||
|
spelling with a different meaning.
|
||||||
|
- `BP` is callee-save. The assembler inserts the save and restore whenever
|
||||||
|
the function has a non-zero frame, so using BP as a general register
|
||||||
|
interferes with sampling profilers that walk the frame chain.
|
||||||
|
- `R14` holds `g`, the goroutine pointer, in the register ABI; `RDX` holds
|
||||||
|
the closure context; `R12` and `R13` are the register ABI's scratch pair
|
||||||
|
and `R15` its GOT temporary; `X15` is the zeroing register the compiler
|
||||||
|
uses. An ABI0 assembly function called from Go sees none of these live
|
||||||
|
across the call, but runtime assembly reads them directly.
|
||||||
|
- The legacy spellings for the goroutine pointer are the macros of
|
||||||
|
`runtime/go_tls.h`: `get_tls(r)` expands to `MOVQ TLS, r` and `g(r)` to
|
||||||
|
`0(r)(TLS*1)`, the segment base riding the index field.
|
||||||
|
|
||||||
|
## Addressing
|
||||||
|
|
||||||
|
The common forms of OPERANDS.md, with the amd64 specifics:
|
||||||
|
|
||||||
|
```text
|
||||||
|
offset(base) MOVQ 16(BX), AX
|
||||||
|
offset(base)(index*scale) MOVL foo+32(SP)(R9*8), CX
|
||||||
|
scale is 1, 2, 4 or 8
|
||||||
|
name±offset(SB) MOVQ ·table(SB), CX
|
||||||
|
```
|
||||||
|
|
||||||
|
- Global references assemble as absolute addresses and produce R_ADDR
|
||||||
|
relocations; branch targets produce R_PCREL.
|
||||||
|
- Vector indexed memory, the VSIB form with an X, Y or Z register in the
|
||||||
|
index position, exists for the gather and scatter families.
|
||||||
|
- There are no segment overrides in source; the one segment-flavoured form
|
||||||
|
is the TLS base in the index field shown above.
|
||||||
|
|
||||||
|
## The frame and the split check
|
||||||
|
|
||||||
|
The assembler manages the frame, not the programmer:
|
||||||
|
|
||||||
|
- It inserts the `BP` save and restore for any non-zero frame.
|
||||||
|
- It inserts the stack-split check for any function that is not NoSplit:
|
||||||
|
the check compares SP against the guard, and on exhaustion calls
|
||||||
|
`runtime.morestack_noctxt`. Frames at or below 128 bytes, StackSmall, use
|
||||||
|
the small compare; frames at or below 4096 bytes, StackBig, use the
|
||||||
|
adjusted form; larger frames compare in two steps.
|
||||||
|
- On amd64 the assembler marks a function NoSplit itself when the frame is
|
||||||
|
under StackSmall and the body calls nothing that needs stack: such a
|
||||||
|
function carries the NoSplit flag in the object without the source ever
|
||||||
|
writing NOSPLIT.
|
||||||
|
|
||||||
|
Results and arguments are stack-only in ABI0: the caller's frame carries
|
||||||
|
them at FP offsets, per the Go prototype.
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
The inventory counts 1654 recognised mnemonics today, of which the encoder
|
||||||
|
emits 1113; both numbers are generated in the appendix, and the gap is the
|
||||||
|
encoder backlog that `gasm audit-instructions` measures. The families:
|
||||||
|
|
||||||
|
- **Integer base.** The ALU and move set with width suffixes, `MOVB`,
|
||||||
|
`MOVW`, `MOVL`, `MOVQ`; the extension moves `MOVBLZX`, `MOVWLSX`,
|
||||||
|
`MOVLQSX` and their siblings, which the compiler's output leans on;
|
||||||
|
`LEA`; `PUSH` and `POP`; the shifts and rotates; the bit operations `BT`
|
||||||
|
through `BTC`, `BSF`, `BSR`, `LZCNT`, `TZCNT`, `POPCNT`, `BSWAP`; the
|
||||||
|
string primitives `MOVS` and `STOS`.
|
||||||
|
- **Exchange and atomics.** `XCHG`, `CMPXCHG`, `XADD`; the extended-carry
|
||||||
|
pair `ADCX` and `ADOX`; `CRC32`.
|
||||||
|
- **Scalar floating point.** The SSE2 scalar moves and arithmetic
|
||||||
|
(`MOVSD`, `MOVSS`, `ADDSD`, and the `CVT` family). Floating-point
|
||||||
|
immediates are not encodable on this target, so the assembler
|
||||||
|
materialises them: the constant lands in a synthesised read-only pool,
|
||||||
|
and a positive zero collapses to `XORPS` of the register with itself,
|
||||||
|
exactly as the toolchain does.
|
||||||
|
- **Legacy SIMD, SSE.** The `MOVO`, `MOVOU`, `MOVAPS` family and the packed
|
||||||
|
integer and floating operations, shuffles, lane extracts and inserts and
|
||||||
|
the imm8-controlled forms.
|
||||||
|
- **VEX and EVEX.** The `V`-prefixed forms for 256 and 512-bit work,
|
||||||
|
opmask operations on `K0` to `K7`, gathers and scatters, and the
|
||||||
|
quad-register families 4FMAPS, 4FNMADD, 4VNNIW, VP4DPWSSD and VP4DPWSSDS,
|
||||||
|
whose register list rides the inverted V′VVV field. Mixing VEX and legacy
|
||||||
|
SSE in one loop pays the AVX-SSE transition penalty on every switch: keep
|
||||||
|
a loop in one dialect.
|
||||||
|
- **Cryptographic and counting extensions.** AES-NI, SHA-1 and SHA-256,
|
||||||
|
PCLMULQDQ, GFNI.
|
||||||
|
- **System.** `CPUID`, `RDTSC`, `SYSCALL`, the fences, `LDMXCSR` and
|
||||||
|
`STMXCSR`, the prefetch family.
|
||||||
|
- **Pseudo-operations.** `BYTE`, `WORD`, `LONG`, `QUAD` lay raw bytes or
|
||||||
|
words into the stream for encodings the assembler does not know; `ADJSP`
|
||||||
|
adjusts the stack pointer; `DUFFCOPY` and `DUFFZERO` and `GETCALLERPC`
|
||||||
|
are compiler-side names the table recognises but an encoder need not
|
||||||
|
emit.
|
||||||
|
|
||||||
|
A mnemonic the appendix lists with `gasm encodes: no` assembles nowhere:
|
||||||
|
gasm reports it as an explicit error, never as wrong bytes, and the
|
||||||
|
`unencodable-instruction` lint flags it at edit time.
|
||||||
|
|
||||||
|
## Relocations
|
||||||
|
|
||||||
|
The relocations an amd64 object carries, all specified in
|
||||||
|
[GOOBJ.md](../GOOBJ.md): `R_ADDR` for absolute globals, `R_PCREL` for
|
||||||
|
relative addresses, `R_CALL` for direct calls, `R_TLS_LE` and `R_TLS_IE` for
|
||||||
|
thread local access and `R_GOTPCREL` for GOT relative sequences, plus
|
||||||
|
`R_DWTXTADDR_U4` inside the DWARF records, which the assembler always
|
||||||
|
emits in the four-byte flavour.
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
# ARM64
|
||||||
|
|
||||||
|
Layer 1, target page. Verified against `go tool asm` of Go 1.27.1, against the
|
||||||
|
toolchain's own arm64 assembler manual (`cmd/internal/obj/arm64/doc.go`) and
|
||||||
|
against gasm's encoder, whose output is compared byte for byte with the
|
||||||
|
toolchain's. The complete mnemonic inventory lives in the generated appendix
|
||||||
|
[INSTRUCTIONS-ARM64.md](INSTRUCTIONS-ARM64.md).
|
||||||
|
|
||||||
|
## Registers
|
||||||
|
|
||||||
|
- General purpose: `R0` to `R30`, plus `ZR`, the zero register, and `RSP`,
|
||||||
|
the stack pointer. There is no R31: thirty-one names and ZR.
|
||||||
|
- Floating-point and SIMD share one file written `Vn`; where an instruction
|
||||||
|
is scalar floating point the operand may be written `Fn` (`F0` to `F31`).
|
||||||
|
- SVE register names (`Z0` to `Z31`, `P0` to `P15`) exist in the assembler's
|
||||||
|
tables.
|
||||||
|
- Roles the convention fixes: `RSP` is the stack pointer, `R29` the frame
|
||||||
|
pointer, `R30` the link register, `R26` the closure context and `R27` the
|
||||||
|
assembler's scratch register. The goroutine pointer lives in `R28` and is
|
||||||
|
written `g` in source, its fields as `g_m(g)`, `g_sched(g)`; `R18` is the
|
||||||
|
platform-reserved register and the Go toolchain never addresses it.
|
||||||
|
|
||||||
|
## Loads, stores and the width suffixes
|
||||||
|
|
||||||
|
The MOV series is the load and store interface, with the width in the
|
||||||
|
mnemonic rather than the register name:
|
||||||
|
|
||||||
|
| Mnemonic | Machine instruction |
|
||||||
|
|---|---|
|
||||||
|
| `MOVD` | ldr, str, stur, 64-bit |
|
||||||
|
| `MOVW` | ldrsw, str, stur, 32-bit sign extending |
|
||||||
|
| `MOVWU` | ldr, 32-bit zero extending |
|
||||||
|
| `MOVH` | ldrsh, strh, sturh |
|
||||||
|
| `MOVHU` | ldrh |
|
||||||
|
| `MOVB` | ldrsb, strb, sturb |
|
||||||
|
| `MOVBU` | ldrb |
|
||||||
|
|
||||||
|
Post-index and pre-index addressing take the `.P` and `.W` suffixes on the
|
||||||
|
mnemonic: `MOVD.P -8(R10), R8` is `ldr x8, [x10],#-8`, and `MOVB.W
|
||||||
|
16(R16), R10` is `ldrsb x10, [x16,#16]!`.
|
||||||
|
|
||||||
|
## Addressing
|
||||||
|
|
||||||
|
```text
|
||||||
|
imm(Rn|RSP) 28(R17)
|
||||||
|
(Rn|RSP) (R22)
|
||||||
|
(Rn)(Rm) (R27)(R23)
|
||||||
|
(Rn)(Rm<<scale) (R4)(R12<<2)
|
||||||
|
(Rn)(Rm.UXTW<<3) extended and shifted index
|
||||||
|
(Rt1, Rt2) register pair for LDP, STP and the exclusive pair forms
|
||||||
|
```
|
||||||
|
|
||||||
|
Branch targets are labels, `(R3)` for indirect, `name(SB)` for static.
|
||||||
|
|
||||||
|
## Operand order and the special forms
|
||||||
|
|
||||||
|
Most instructions appear in left-to-right assignment order: `ADD R11,
|
||||||
|
RSP, R25` computes into R25. The exceptions the toolchain's manual lists,
|
||||||
|
each with its own order:
|
||||||
|
|
||||||
|
- stores and `CBZ`, `CBNZ` keep the GNU order: `MOVD R29, 384(R19)`.
|
||||||
|
- The multiply-accumulate family `MADD`, `MSUB`, `SMADDL` and friends are
|
||||||
|
`<Rm>, <Ra>, <Rn>, <Rd>`.
|
||||||
|
- The scalar FMA family `FMADDD` and friends are `<Fm>, <Fa>, <Fn>, <Fd>`.
|
||||||
|
- The bitfield family `BFI`, `BFXIL`, `SBFIZ`, `SBFX`, `UBFIZ`, `UBFX` is
|
||||||
|
`$<lsb>, <Rn>, $<width>, <Rd>`.
|
||||||
|
- The conditional compare and select families carry the condition as the
|
||||||
|
**first** operand: `CSEL GT, R0, R19, R1`, `CCMP MI, R22, $12, $13`,
|
||||||
|
`FCCMPD AL, F8, F26, $0`.
|
||||||
|
- The exclusive stores are `<Rf>, (<Rn>), <Rs>` with the status register
|
||||||
|
last: `STLXR ZR, (R15), R16`.
|
||||||
|
- `TBZ` and `TBNZ` are `$<imm>, <Rt>, <label>`.
|
||||||
|
|
||||||
|
Shifted and extended register operands ride the register: `R19>>30`,
|
||||||
|
`R26->24` for arithmetic right shift, `@>` for rotate, and the extend forms
|
||||||
|
`R19.UXTB<<4`, `R14.SXTX` with extend operators UXTB, UXTH, UXTW, UXTX,
|
||||||
|
SXTB, SXTH, SXTW, SXTX.
|
||||||
|
|
||||||
|
## Conditions, branches and names
|
||||||
|
|
||||||
|
- Conditions ride the branch mnemonic: `B.EQ`, or the canonical
|
||||||
|
per-condition names such as `BEQ`. Both spellings exist; the canonical
|
||||||
|
names are what the generated inventory lists.
|
||||||
|
- `br` is `JMP` and `blr` is `CALL` in this dialect; indirect branches are
|
||||||
|
`JMP (R3)` and `CALL (R17)`.
|
||||||
|
- `NOP` is a zero-width pseudo-instruction; the hardware nop is `NOOP`,
|
||||||
|
an alias of `HINT $0`.
|
||||||
|
- `umov` is written as `VMOV`.
|
||||||
|
|
||||||
|
## Constants
|
||||||
|
|
||||||
|
- A 16-bit immediate optionally shifted: `MOVK $(10<<32), R20`, with
|
||||||
|
`MOVZ`, `MOVN` and their W variants; a zero shift is rejected by the
|
||||||
|
assembler.
|
||||||
|
- Large integer constants: `MOV` materialises any 64-bit constant, the
|
||||||
|
closest-instruction way.
|
||||||
|
- Vector constants: `VMOVS`, `VMOVD` and `VMOVQ`, the last taking two
|
||||||
|
64-bit halves for a 128-bit value:
|
||||||
|
`VMOVQ $0x1122334455667788, $0x99aabbccddeeff00, V2`.
|
||||||
|
|
||||||
|
## SIMD
|
||||||
|
|
||||||
|
Floating-point and SIMD instructions mostly carry a `V` prefix
|
||||||
|
(`VADD`, `VFMLA`), the cryptographic extensions (`AESD`, `SHA256H`) and the
|
||||||
|
scalar floating-point instructions being the exceptions. Operands carry an
|
||||||
|
arrangement suffix, `V5.H8`, and structure loads and stores use bracket
|
||||||
|
lists, `[V21.B16]`, with element selection as `V9.S[1]`.
|
||||||
|
|
||||||
|
## Alignment
|
||||||
|
|
||||||
|
`PCALIGN $n` pads to a power-of-two boundary between 8 and 2048 and also
|
||||||
|
raises the function's alignment to the coarsest boundary any of its PCALIGN
|
||||||
|
directives asks for. Functions default to 16-byte alignment on this target.
|
||||||
|
|
||||||
|
## Relocations
|
||||||
|
|
||||||
|
`R_ADDRARM64` for the adrp-plus-add pair, `R_ARM64_PCREL` and the
|
||||||
|
`R_ARM64_PCREL_LDST` family for PC relative addressing, `R_ARM64_LDST` for
|
||||||
|
the load and store immediates, `R_ARM64_GOTPCREL` and `R_ARM64_GOT` for the
|
||||||
|
GOT, `R_ARM64_TLS_LE` and `R_ARM64_TLS_IE` for thread local storage and
|
||||||
|
`R_CALLARM64` for direct calls, all specified in
|
||||||
|
[GOOBJ.md](../GOOBJ.md).
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
# Directives: TEXT, DATA, GLOBL and the annotations
|
||||||
|
|
||||||
|
Layer 1, the common language, with the flag vocabulary both layers share.
|
||||||
|
Verified against `go tool asm` of Go 1.27.1, against the shipped headers
|
||||||
|
`textflag.h` and `funcdata.h` in `$GOROOT/pkg/include`, and against gasm's
|
||||||
|
parser. Where gasm extends a directive, the extension says so and is marked.
|
||||||
|
|
||||||
|
Six directives exist. Three define things: TEXT, DATA, GLOBL. Three
|
||||||
|
annotate: FUNCDATA, PCDATA, PCALIGN.
|
||||||
|
|
||||||
|
## TEXT
|
||||||
|
|
||||||
|
```text
|
||||||
|
// func Add(a, b int64) int64
|
||||||
|
TEXT ·Add(SB), NOSPLIT, $0-24
|
||||||
|
...instructions...
|
||||||
|
RET
|
||||||
|
```
|
||||||
|
|
||||||
|
```text
|
||||||
|
TEXT symbol(SB), [flags,] $framesize[-argsize]
|
||||||
|
```
|
||||||
|
|
||||||
|
- The symbol is an `·Name(SB)` reference into the current package, or a
|
||||||
|
fully qualified name.
|
||||||
|
- The optional flag argument is a constant expression, normally an OR of the
|
||||||
|
names from `textflag.h`, the table below. Without `#include "textflag.h"`
|
||||||
|
the names are not macros and the assembler reports the misleading error
|
||||||
|
`illegal or missing addressing mode for symbol NOSPLIT`: include the
|
||||||
|
header first.
|
||||||
|
- `$framesize-argsize` is two constants, not a subtraction: the local frame
|
||||||
|
size in bytes, and the caller's argument area in bytes. The argument size
|
||||||
|
may be omitted entirely, `$16`, which marks the argument size unknown
|
||||||
|
(0x80000000 in the object, the value of `ArgsSizeUnknown` from
|
||||||
|
`funcdata.h`); a frame size may be negative only in the generated ABI
|
||||||
|
wrappers.
|
||||||
|
- A function whose last instruction is not a branch cannot fall through into
|
||||||
|
the next TEXT: the toolchain appends a jump to itself, so end functions
|
||||||
|
with `RET` deliberately.
|
||||||
|
- One TEXT per symbol; redeclaring is an error. The TEXT line also fixes the
|
||||||
|
function's source line for traceback: it is the line number that pcln
|
||||||
|
reports for the function's start.
|
||||||
|
|
||||||
|
The framesize and argsize fields do real work: the framesize drives the
|
||||||
|
stack-split preamble (RUNTIME.md carries the contract), and both travel into
|
||||||
|
the FuncInfo record of the object (GOOBJ.md carries its layout).
|
||||||
|
|
||||||
|
### The flag table
|
||||||
|
|
||||||
|
Values from `textflag.h`, in agreement with `cmd/internal/obj/textflag.go`:
|
||||||
|
|
||||||
|
| Name | Value | Applies to | Meaning |
|
||||||
|
|---|---|---|---|
|
||||||
|
| NOPROF | 1 | both | do not profile; deprecated |
|
||||||
|
| DUPOK | 2 | both | the linker may keep one of several duplicates |
|
||||||
|
| NOSPLIT | 4 | TEXT | no stack-split preamble |
|
||||||
|
| RODATA | 8 | data | put the data in a read-only section |
|
||||||
|
| NOPTR | 16 | data | the data contains no pointers |
|
||||||
|
| WRAPPER | 32 | TEXT | a wrapper; must not disable `recover` |
|
||||||
|
| NEEDCTXT | 64 | TEXT | a closure consuming the context register |
|
||||||
|
| TLSBSS | 256 | data | a thread local word in BSS |
|
||||||
|
| NOFRAME | 512 | TEXT | no frame setup; only valid with a frame size of 0 |
|
||||||
|
| REFLECTMETHOD | 1024 | TEXT | the function calls `reflect.Type.Method` or `MethodByName` |
|
||||||
|
| TOPFRAME | 2048 | TEXT | the outermost frame; unwinders stop here |
|
||||||
|
| ABIWRAPPER | 4096 | TEXT | an ABI transition wrapper |
|
||||||
|
|
||||||
|
Rules with teeth:
|
||||||
|
|
||||||
|
- `NOSPLIT` removes the split check, so the frame plus everything the
|
||||||
|
function calls must fit in the stack segment that remains. It exists to
|
||||||
|
protect the splitting code itself; reaching for it to save two instructions
|
||||||
|
is how stack overflows corrupt memory. On amd64 the assembler additionally
|
||||||
|
marks small leaf functions NoSplit itself and omits the check, so the
|
||||||
|
absence of the preamble is not proof the flag was written.
|
||||||
|
- A TEXT whose symbol is declared `ABIInternal` must carry NOSPLIT: the
|
||||||
|
assembler rejects it otherwise, because it cannot generate
|
||||||
|
the split path for a register-ABI function.
|
||||||
|
- `RODATA` implies NOPTR for the garbage collector.
|
||||||
|
|
||||||
|
## DATA
|
||||||
|
|
||||||
|
```text
|
||||||
|
DATA ·table+0(SB)/8, $0x0102030405060708
|
||||||
|
DATA ·msg+0(SB)/14, $"hello, world\n"
|
||||||
|
GLOBL ·msg(SB), RODATA, $14
|
||||||
|
```
|
||||||
|
|
||||||
|
```text
|
||||||
|
DATA symbol+offset(SB)/width, value
|
||||||
|
```
|
||||||
|
|
||||||
|
- `width` is exactly 1, 2, 4 or 8: the initialiser is written into the data
|
||||||
|
image at `symbol+offset` in that many bytes.
|
||||||
|
- The value is an integer or character constant of the width, or a string
|
||||||
|
literal whose byte length equals the width exactly; escapes count. Long
|
||||||
|
data is written as successive DATA lines at increasing offsets; bytes the
|
||||||
|
directives never name are zero.
|
||||||
|
- Every symbol initialised with DATA ends with a GLOBL line declaring its
|
||||||
|
total size, after all of its DATA lines.
|
||||||
|
|
||||||
|
A symbol containing pointers cannot be defined in assembly, because the
|
||||||
|
collector cannot see into it: define it in Go and refer to it by name. As a
|
||||||
|
rule, data that is not read-only belongs in Go.
|
||||||
|
|
||||||
|
Extension, gasm only: a DATA initialiser may name a symbol,
|
||||||
|
`DATA ·fn+0(SB)/8, $·handler(SB)`, which gasm lays down as an absolute
|
||||||
|
relocation on that field. The toolchain offers no ground truth for this
|
||||||
|
form; gasm's behaviour is verified by linking and execution.
|
||||||
|
|
||||||
|
## GLOBL
|
||||||
|
|
||||||
|
```text
|
||||||
|
GLOBL symbol(SB), [flags,] $size
|
||||||
|
```
|
||||||
|
|
||||||
|
Declares the symbol global with its total size in bytes. The useful flags
|
||||||
|
are RODATA, NOPTR, DUPOK and TLSBSS from the table above. Uninitialised
|
||||||
|
bytes are zero, which makes GLOBL with no DATA the language's BSS.
|
||||||
|
|
||||||
|
## FUNCDATA and PCDATA
|
||||||
|
|
||||||
|
```text
|
||||||
|
FUNCDATA $functypeid, symbol(SB)
|
||||||
|
PCDATA $pctypeid, $value
|
||||||
|
```
|
||||||
|
|
||||||
|
The compiler's annotations for the garbage collector and traceback, named by
|
||||||
|
the ids in `funcdata.h`: FUNCDATA 0 to 7 (args pointer maps, locals pointer
|
||||||
|
maps, stack objects, inline tree, open-coded defer info, argument info,
|
||||||
|
argument liveness, wrap info), PCDATA 0 to 4 (unsafe point, stack map index,
|
||||||
|
inline tree index, argument liveness index, panic bounds). Assembly code
|
||||||
|
normally reaches them only through the macro forms in `funcdata.h`, which
|
||||||
|
RUNTIME.md explains. Outside the macros, hand-written PCDATA is meaningless:
|
||||||
|
the values are pc-value tables the compiler builds from its own view of the
|
||||||
|
program.
|
||||||
|
|
||||||
|
## PCALIGN
|
||||||
|
|
||||||
|
```text
|
||||||
|
PCALIGN $32
|
||||||
|
```
|
||||||
|
|
||||||
|
Pads the code so that the next instruction lands on the given boundary,
|
||||||
|
which must be a power of two and at least the target's instruction
|
||||||
|
alignment. Supported on amd64, arm64, ppc64, loong64 and riscv64. The
|
||||||
|
padding instructions are the target's NOP encoding, so the bytes between
|
||||||
|
functions differ from what the instruction stream alone would produce, which
|
||||||
|
matters to anyone comparing encodings byte for byte.
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,570 @@
|
|||||||
|
# ARM64: instruction inventory
|
||||||
|
|
||||||
|
Generated by gasm-devkit's `_gen` from the Go toolchain's instruction table
|
||||||
|
(`cmd/internal/obj/arm64/anames.go`, go1.27.1); DO NOT EDIT. This page lists every mnemonic
|
||||||
|
`go tool asm` accepts on this target, which is the upper bound of the
|
||||||
|
language on it: a name absent here is not an instruction of the target,
|
||||||
|
and a name present here may still be one gasm's encoder cannot emit yet.
|
||||||
|
|
||||||
|
The inventory carries no per-mnemonic encoder column: on this target
|
||||||
|
encodability is decided per operand shape, and the live measured
|
||||||
|
coverage is reported by `gasm audit-instructions`.
|
||||||
|
|
||||||
|
| Mnemonic | Notes |
|
||||||
|
|---|---|
|
||||||
|
| `CALL` | |
|
||||||
|
| `DUFFCOPY` | |
|
||||||
|
| `DUFFZERO` | |
|
||||||
|
| `END` | |
|
||||||
|
| `FUNCDATA` | |
|
||||||
|
| `GETCALLERPC` | |
|
||||||
|
| `JMP` | |
|
||||||
|
| `NOP` | No operation |
|
||||||
|
| `PCALIGN` | |
|
||||||
|
| `PCALIGNMAX` | |
|
||||||
|
| `PCDATA` | |
|
||||||
|
| `RET` | Return |
|
||||||
|
| `TEXT` | |
|
||||||
|
| `UNDEF` | |
|
||||||
|
| `ADC` | ADC (64-bit) |
|
||||||
|
| `ADCS` | ADCS (64-bit) |
|
||||||
|
| `ADCSW` | ADCS (32-bit) |
|
||||||
|
| `ADCW` | ADC (32-bit) |
|
||||||
|
| `ADD` | ADD (64-bit) |
|
||||||
|
| `ADDS` | ADDS (64-bit) |
|
||||||
|
| `ADDSW` | ADDS (32-bit) |
|
||||||
|
| `ADDW` | ADD (32-bit) |
|
||||||
|
| `ADR` | Address of label/page |
|
||||||
|
| `ADRP` | Address of label/page |
|
||||||
|
| `AESD` | AES round |
|
||||||
|
| `AESE` | AES round |
|
||||||
|
| `AESIMC` | AES round |
|
||||||
|
| `AESMC` | AES round |
|
||||||
|
| `AND` | AND (64-bit) |
|
||||||
|
| `ANDS` | ANDS (64-bit) |
|
||||||
|
| `ANDSW` | ANDS (32-bit) |
|
||||||
|
| `ANDW` | AND (32-bit) |
|
||||||
|
| `ASR` | ASR shift |
|
||||||
|
| `ASRW` | ASR shift (32-bit) |
|
||||||
|
| `AT` | |
|
||||||
|
| `AUTIA1716` | |
|
||||||
|
| `AUTIASP` | |
|
||||||
|
| `AUTIB1716` | |
|
||||||
|
| `AUTIBSP` | |
|
||||||
|
| `BCC` | Conditional branch |
|
||||||
|
| `BCS` | Conditional branch |
|
||||||
|
| `BEQ` | Conditional branch |
|
||||||
|
| `BFI` | |
|
||||||
|
| `BFIW` | |
|
||||||
|
| `BFM` | |
|
||||||
|
| `BFMW` | |
|
||||||
|
| `BFXIL` | Bitfield extract |
|
||||||
|
| `BFXILW` | |
|
||||||
|
| `BGE` | Conditional branch |
|
||||||
|
| `BGT` | Conditional branch |
|
||||||
|
| `BHI` | Conditional branch |
|
||||||
|
| `BHS` | Conditional branch |
|
||||||
|
| `BIC` | BIC (64-bit) |
|
||||||
|
| `BICS` | BICS (64-bit) |
|
||||||
|
| `BICSW` | BICS (32-bit) |
|
||||||
|
| `BICW` | BIC (32-bit) |
|
||||||
|
| `BLE` | Conditional branch |
|
||||||
|
| `BLO` | Conditional branch |
|
||||||
|
| `BLS` | Conditional branch |
|
||||||
|
| `BLT` | Conditional branch |
|
||||||
|
| `BMI` | Conditional branch |
|
||||||
|
| `BNE` | Conditional branch |
|
||||||
|
| `BPL` | Conditional branch |
|
||||||
|
| `BRK` | Breakpoint |
|
||||||
|
| `BTI` | |
|
||||||
|
| `BVC` | Conditional branch |
|
||||||
|
| `BVS` | Conditional branch |
|
||||||
|
| `CASAD` | |
|
||||||
|
| `CASALB` | |
|
||||||
|
| `CASALD` | |
|
||||||
|
| `CASALH` | |
|
||||||
|
| `CASALW` | |
|
||||||
|
| `CASAW` | |
|
||||||
|
| `CASB` | |
|
||||||
|
| `CASD` | |
|
||||||
|
| `CASH` | |
|
||||||
|
| `CASLD` | |
|
||||||
|
| `CASLW` | |
|
||||||
|
| `CASPD` | |
|
||||||
|
| `CASPW` | |
|
||||||
|
| `CASW` | |
|
||||||
|
| `CBNZ` | Compare/test and branch |
|
||||||
|
| `CBNZW` | Compare/test and branch (32-bit) |
|
||||||
|
| `CBZ` | Compare/test and branch |
|
||||||
|
| `CBZW` | Compare/test and branch (32-bit) |
|
||||||
|
| `CCMN` | Conditional compare |
|
||||||
|
| `CCMNW` | Conditional compare |
|
||||||
|
| `CCMP` | Conditional compare |
|
||||||
|
| `CCMPW` | Conditional compare |
|
||||||
|
| `CINC` | Conditional select |
|
||||||
|
| `CINCW` | Conditional select (32-bit) |
|
||||||
|
| `CINV` | Conditional select |
|
||||||
|
| `CINVW` | Conditional select (32-bit) |
|
||||||
|
| `CLREX` | |
|
||||||
|
| `CLS` | Bit manipulation |
|
||||||
|
| `CLSW` | Bit manipulation |
|
||||||
|
| `CLZ` | Bit manipulation |
|
||||||
|
| `CLZW` | Bit manipulation |
|
||||||
|
| `CMN` | CMN (64-bit) |
|
||||||
|
| `CMNW` | CMN (32-bit) |
|
||||||
|
| `CMP` | CMP (64-bit) |
|
||||||
|
| `CMPW` | CMP (32-bit) |
|
||||||
|
| `CNEG` | Conditional select |
|
||||||
|
| `CNEGW` | Conditional select (32-bit) |
|
||||||
|
| `CRC32B` | |
|
||||||
|
| `CRC32CB` | |
|
||||||
|
| `CRC32CH` | |
|
||||||
|
| `CRC32CW` | |
|
||||||
|
| `CRC32CX` | |
|
||||||
|
| `CRC32H` | |
|
||||||
|
| `CRC32W` | |
|
||||||
|
| `CRC32X` | |
|
||||||
|
| `CSEL` | Conditional select |
|
||||||
|
| `CSELW` | Conditional select (32-bit) |
|
||||||
|
| `CSET` | Conditional select |
|
||||||
|
| `CSETM` | Conditional select |
|
||||||
|
| `CSETMW` | Conditional select (32-bit) |
|
||||||
|
| `CSETW` | Conditional select (32-bit) |
|
||||||
|
| `CSINC` | Conditional select |
|
||||||
|
| `CSINCW` | Conditional select (32-bit) |
|
||||||
|
| `CSINV` | Conditional select |
|
||||||
|
| `CSINVW` | Conditional select (32-bit) |
|
||||||
|
| `CSNEG` | Conditional select |
|
||||||
|
| `CSNEGW` | Conditional select (32-bit) |
|
||||||
|
| `DC` | Data cache maintenance |
|
||||||
|
| `DCPS1` | |
|
||||||
|
| `DCPS2` | |
|
||||||
|
| `DCPS3` | |
|
||||||
|
| `DMB` | Barrier |
|
||||||
|
| `DRPS` | |
|
||||||
|
| `DSB` | Barrier |
|
||||||
|
| `DWORD` | |
|
||||||
|
| `EON` | EON (64-bit) |
|
||||||
|
| `EONW` | EON (32-bit) |
|
||||||
|
| `EOR` | EOR (64-bit) |
|
||||||
|
| `EORW` | EOR (32-bit) |
|
||||||
|
| `ERET` | |
|
||||||
|
| `EXTR` | Bitfield extract |
|
||||||
|
| `EXTRW` | |
|
||||||
|
| `FABSD` | |
|
||||||
|
| `FABSS` | |
|
||||||
|
| `FADDD` | |
|
||||||
|
| `FADDS` | |
|
||||||
|
| `FCCMPD` | |
|
||||||
|
| `FCCMPED` | |
|
||||||
|
| `FCCMPES` | |
|
||||||
|
| `FCCMPS` | |
|
||||||
|
| `FCMPD` | |
|
||||||
|
| `FCMPED` | |
|
||||||
|
| `FCMPES` | |
|
||||||
|
| `FCMPS` | |
|
||||||
|
| `FCSELD` | |
|
||||||
|
| `FCSELS` | |
|
||||||
|
| `FCVTDH` | |
|
||||||
|
| `FCVTDS` | |
|
||||||
|
| `FCVTHD` | |
|
||||||
|
| `FCVTHS` | |
|
||||||
|
| `FCVTSD` | |
|
||||||
|
| `FCVTSH` | |
|
||||||
|
| `FCVTZSD` | |
|
||||||
|
| `FCVTZSDW` | |
|
||||||
|
| `FCVTZSS` | |
|
||||||
|
| `FCVTZSSW` | |
|
||||||
|
| `FCVTZUD` | |
|
||||||
|
| `FCVTZUDW` | |
|
||||||
|
| `FCVTZUS` | |
|
||||||
|
| `FCVTZUSW` | |
|
||||||
|
| `FDIVD` | |
|
||||||
|
| `FDIVS` | |
|
||||||
|
| `FLDPD` | Register-pair load or store |
|
||||||
|
| `FLDPQ` | |
|
||||||
|
| `FLDPS` | |
|
||||||
|
| `FMADDD` | |
|
||||||
|
| `FMADDS` | |
|
||||||
|
| `FMAXD` | |
|
||||||
|
| `FMAXNMD` | |
|
||||||
|
| `FMAXNMS` | |
|
||||||
|
| `FMAXS` | |
|
||||||
|
| `FMIND` | |
|
||||||
|
| `FMINNMD` | |
|
||||||
|
| `FMINNMS` | |
|
||||||
|
| `FMINS` | |
|
||||||
|
| `FMOVD` | Move / load / store |
|
||||||
|
| `FMOVQ` | |
|
||||||
|
| `FMOVS` | Move / load / store |
|
||||||
|
| `FMSUBD` | |
|
||||||
|
| `FMSUBS` | |
|
||||||
|
| `FMULD` | |
|
||||||
|
| `FMULS` | |
|
||||||
|
| `FNEGD` | |
|
||||||
|
| `FNEGS` | |
|
||||||
|
| `FNMADDD` | |
|
||||||
|
| `FNMADDS` | |
|
||||||
|
| `FNMSUBD` | |
|
||||||
|
| `FNMSUBS` | |
|
||||||
|
| `FNMULD` | |
|
||||||
|
| `FNMULS` | |
|
||||||
|
| `FRINTAD` | |
|
||||||
|
| `FRINTAS` | |
|
||||||
|
| `FRINTID` | |
|
||||||
|
| `FRINTIS` | |
|
||||||
|
| `FRINTMD` | |
|
||||||
|
| `FRINTMS` | |
|
||||||
|
| `FRINTND` | |
|
||||||
|
| `FRINTNS` | |
|
||||||
|
| `FRINTPD` | |
|
||||||
|
| `FRINTPS` | |
|
||||||
|
| `FRINTXD` | |
|
||||||
|
| `FRINTXS` | |
|
||||||
|
| `FRINTZD` | |
|
||||||
|
| `FRINTZS` | |
|
||||||
|
| `FSQRTD` | |
|
||||||
|
| `FSQRTS` | |
|
||||||
|
| `FSTPD` | Register-pair load or store |
|
||||||
|
| `FSTPQ` | |
|
||||||
|
| `FSTPS` | |
|
||||||
|
| `FSUBD` | |
|
||||||
|
| `FSUBS` | |
|
||||||
|
| `HINT` | |
|
||||||
|
| `HLT` | |
|
||||||
|
| `HVC` | Exception generation |
|
||||||
|
| `IC` | |
|
||||||
|
| `ISB` | Barrier |
|
||||||
|
| `LDADDAB` | |
|
||||||
|
| `LDADDAD` | |
|
||||||
|
| `LDADDAH` | |
|
||||||
|
| `LDADDALB` | |
|
||||||
|
| `LDADDALD` | |
|
||||||
|
| `LDADDALH` | |
|
||||||
|
| `LDADDALW` | |
|
||||||
|
| `LDADDAW` | |
|
||||||
|
| `LDADDB` | |
|
||||||
|
| `LDADDD` | |
|
||||||
|
| `LDADDH` | |
|
||||||
|
| `LDADDLB` | |
|
||||||
|
| `LDADDLD` | |
|
||||||
|
| `LDADDLH` | |
|
||||||
|
| `LDADDLW` | |
|
||||||
|
| `LDADDW` | |
|
||||||
|
| `LDAR` | Atomic memory operation |
|
||||||
|
| `LDARB` | Atomic memory operation |
|
||||||
|
| `LDARH` | Atomic memory operation |
|
||||||
|
| `LDARW` | Atomic memory operation |
|
||||||
|
| `LDAXP` | |
|
||||||
|
| `LDAXPW` | |
|
||||||
|
| `LDAXR` | Atomic memory operation |
|
||||||
|
| `LDAXRB` | Atomic memory operation |
|
||||||
|
| `LDAXRH` | Atomic memory operation |
|
||||||
|
| `LDAXRW` | Atomic memory operation |
|
||||||
|
| `LDCLRAB` | |
|
||||||
|
| `LDCLRAD` | |
|
||||||
|
| `LDCLRAH` | |
|
||||||
|
| `LDCLRALB` | |
|
||||||
|
| `LDCLRALD` | |
|
||||||
|
| `LDCLRALH` | |
|
||||||
|
| `LDCLRALW` | |
|
||||||
|
| `LDCLRAW` | |
|
||||||
|
| `LDCLRB` | |
|
||||||
|
| `LDCLRD` | |
|
||||||
|
| `LDCLRH` | |
|
||||||
|
| `LDCLRLB` | |
|
||||||
|
| `LDCLRLD` | |
|
||||||
|
| `LDCLRLH` | |
|
||||||
|
| `LDCLRLW` | |
|
||||||
|
| `LDCLRW` | |
|
||||||
|
| `LDEORAB` | |
|
||||||
|
| `LDEORAD` | |
|
||||||
|
| `LDEORAH` | |
|
||||||
|
| `LDEORALB` | |
|
||||||
|
| `LDEORALD` | |
|
||||||
|
| `LDEORALH` | |
|
||||||
|
| `LDEORALW` | |
|
||||||
|
| `LDEORAW` | |
|
||||||
|
| `LDEORB` | |
|
||||||
|
| `LDEORD` | |
|
||||||
|
| `LDEORH` | |
|
||||||
|
| `LDEORLB` | |
|
||||||
|
| `LDEORLD` | |
|
||||||
|
| `LDEORLH` | |
|
||||||
|
| `LDEORLW` | |
|
||||||
|
| `LDEORW` | |
|
||||||
|
| `LDORAB` | |
|
||||||
|
| `LDORAD` | |
|
||||||
|
| `LDORAH` | |
|
||||||
|
| `LDORALB` | |
|
||||||
|
| `LDORALD` | |
|
||||||
|
| `LDORALH` | |
|
||||||
|
| `LDORALW` | |
|
||||||
|
| `LDORAW` | |
|
||||||
|
| `LDORB` | |
|
||||||
|
| `LDORD` | |
|
||||||
|
| `LDORH` | |
|
||||||
|
| `LDORLB` | |
|
||||||
|
| `LDORLD` | |
|
||||||
|
| `LDORLH` | |
|
||||||
|
| `LDORLW` | |
|
||||||
|
| `LDORW` | |
|
||||||
|
| `LDP` | Register-pair load or store |
|
||||||
|
| `LDPSW` | |
|
||||||
|
| `LDPW` | Register-pair load or store |
|
||||||
|
| `LDXP` | |
|
||||||
|
| `LDXPW` | |
|
||||||
|
| `LDXR` | |
|
||||||
|
| `LDXRB` | |
|
||||||
|
| `LDXRH` | |
|
||||||
|
| `LDXRW` | |
|
||||||
|
| `LSL` | LSL shift |
|
||||||
|
| `LSLW` | LSL shift (32-bit) |
|
||||||
|
| `LSR` | LSR shift |
|
||||||
|
| `LSRW` | LSR shift (32-bit) |
|
||||||
|
| `MADD` | Multiply / multiply-accumulate |
|
||||||
|
| `MADDW` | |
|
||||||
|
| `MNEG` | Multiply / multiply-accumulate |
|
||||||
|
| `MNEGW` | |
|
||||||
|
| `MOVB` | Move / load / store |
|
||||||
|
| `MOVBU` | Move / load / store |
|
||||||
|
| `MOVD` | Move / load / store |
|
||||||
|
| `MOVH` | Move / load / store |
|
||||||
|
| `MOVHU` | Move / load / store |
|
||||||
|
| `MOVK` | Move wide constant |
|
||||||
|
| `MOVKW` | Move wide constant |
|
||||||
|
| `MOVN` | Move wide constant |
|
||||||
|
| `MOVNW` | Move wide constant |
|
||||||
|
| `MOVP` | |
|
||||||
|
| `MOVPD` | |
|
||||||
|
| `MOVPQ` | |
|
||||||
|
| `MOVPS` | |
|
||||||
|
| `MOVPSW` | |
|
||||||
|
| `MOVPW` | |
|
||||||
|
| `MOVW` | Move / load / store |
|
||||||
|
| `MOVWU` | Move / load / store |
|
||||||
|
| `MOVZ` | Move wide constant |
|
||||||
|
| `MOVZW` | Move wide constant |
|
||||||
|
| `MRS` | System register access |
|
||||||
|
| `MSR` | System register access |
|
||||||
|
| `MSUB` | Multiply / multiply-accumulate |
|
||||||
|
| `MSUBW` | |
|
||||||
|
| `MUL` | Multiply / multiply-accumulate |
|
||||||
|
| `MULW` | |
|
||||||
|
| `MVN` | MVN (64-bit) |
|
||||||
|
| `MVNW` | MVN (32-bit) |
|
||||||
|
| `NEG` | NEG (64-bit) |
|
||||||
|
| `NEGS` | |
|
||||||
|
| `NEGSW` | |
|
||||||
|
| `NEGW` | NEG (32-bit) |
|
||||||
|
| `NGC` | NGC (64-bit) |
|
||||||
|
| `NGCS` | |
|
||||||
|
| `NGCSW` | |
|
||||||
|
| `NGCW` | NGC (32-bit) |
|
||||||
|
| `NOOP` | |
|
||||||
|
| `ORN` | ORN (64-bit) |
|
||||||
|
| `ORNW` | ORN (32-bit) |
|
||||||
|
| `ORR` | ORR (64-bit) |
|
||||||
|
| `ORRW` | ORR (32-bit) |
|
||||||
|
| `PACIASP` | |
|
||||||
|
| `PACIBSP` | |
|
||||||
|
| `PRFM` | Memory prefetch |
|
||||||
|
| `PRFUM` | |
|
||||||
|
| `RBIT` | Bit manipulation |
|
||||||
|
| `RBITW` | Bit manipulation |
|
||||||
|
| `REM` | |
|
||||||
|
| `REMW` | |
|
||||||
|
| `REV` | Bit manipulation |
|
||||||
|
| `REV16` | Bit manipulation |
|
||||||
|
| `REV16W` | |
|
||||||
|
| `REV32` | Bit manipulation |
|
||||||
|
| `REVW` | Bit manipulation |
|
||||||
|
| `ROR` | ROR shift |
|
||||||
|
| `RORW` | ROR shift (32-bit) |
|
||||||
|
| `SBC` | SBC (64-bit) |
|
||||||
|
| `SBCS` | SBCS (64-bit) |
|
||||||
|
| `SBCSW` | SBCS (32-bit) |
|
||||||
|
| `SBCW` | SBC (32-bit) |
|
||||||
|
| `SBFIZ` | |
|
||||||
|
| `SBFIZW` | |
|
||||||
|
| `SBFM` | Bitfield extract |
|
||||||
|
| `SBFMW` | |
|
||||||
|
| `SBFX` | Bitfield extract |
|
||||||
|
| `SBFXW` | |
|
||||||
|
| `SCVTFD` | |
|
||||||
|
| `SCVTFS` | |
|
||||||
|
| `SCVTFWD` | |
|
||||||
|
| `SCVTFWS` | |
|
||||||
|
| `SDIV` | Divide |
|
||||||
|
| `SDIVW` | Divide |
|
||||||
|
| `SEV` | |
|
||||||
|
| `SEVL` | |
|
||||||
|
| `SHA1C` | SHA round |
|
||||||
|
| `SHA1H` | SHA round |
|
||||||
|
| `SHA1M` | SHA round |
|
||||||
|
| `SHA1P` | SHA round |
|
||||||
|
| `SHA1SU0` | SHA round |
|
||||||
|
| `SHA1SU1` | SHA round |
|
||||||
|
| `SHA256H` | SHA round |
|
||||||
|
| `SHA256H2` | SHA round |
|
||||||
|
| `SHA256SU0` | SHA round |
|
||||||
|
| `SHA256SU1` | SHA round |
|
||||||
|
| `SHA512H` | SHA round |
|
||||||
|
| `SHA512H2` | SHA round |
|
||||||
|
| `SHA512SU0` | SHA round |
|
||||||
|
| `SHA512SU1` | SHA round |
|
||||||
|
| `SMADDL` | Multiply / multiply-accumulate |
|
||||||
|
| `SMC` | Exception generation |
|
||||||
|
| `SMNEGL` | |
|
||||||
|
| `SMSUBL` | Multiply / multiply-accumulate |
|
||||||
|
| `SMULH` | Multiply / multiply-accumulate |
|
||||||
|
| `SMULL` | Multiply / multiply-accumulate |
|
||||||
|
| `STLR` | Atomic memory operation |
|
||||||
|
| `STLRB` | Atomic memory operation |
|
||||||
|
| `STLRH` | Atomic memory operation |
|
||||||
|
| `STLRW` | Atomic memory operation |
|
||||||
|
| `STLXP` | |
|
||||||
|
| `STLXPW` | |
|
||||||
|
| `STLXR` | |
|
||||||
|
| `STLXRB` | |
|
||||||
|
| `STLXRH` | |
|
||||||
|
| `STLXRW` | |
|
||||||
|
| `STP` | Register-pair load or store |
|
||||||
|
| `STPW` | Register-pair load or store |
|
||||||
|
| `STXP` | |
|
||||||
|
| `STXPW` | |
|
||||||
|
| `STXR` | Atomic memory operation |
|
||||||
|
| `STXRB` | Atomic memory operation |
|
||||||
|
| `STXRH` | Atomic memory operation |
|
||||||
|
| `STXRW` | Atomic memory operation |
|
||||||
|
| `SUB` | SUB (64-bit) |
|
||||||
|
| `SUBS` | SUBS (64-bit) |
|
||||||
|
| `SUBSW` | SUBS (32-bit) |
|
||||||
|
| `SUBW` | SUB (32-bit) |
|
||||||
|
| `SVC` | Exception generation |
|
||||||
|
| `SWPAB` | |
|
||||||
|
| `SWPAD` | |
|
||||||
|
| `SWPAH` | |
|
||||||
|
| `SWPALB` | |
|
||||||
|
| `SWPALD` | |
|
||||||
|
| `SWPALH` | |
|
||||||
|
| `SWPALW` | |
|
||||||
|
| `SWPAW` | |
|
||||||
|
| `SWPB` | |
|
||||||
|
| `SWPD` | |
|
||||||
|
| `SWPH` | |
|
||||||
|
| `SWPLB` | |
|
||||||
|
| `SWPLD` | |
|
||||||
|
| `SWPLH` | |
|
||||||
|
| `SWPLW` | |
|
||||||
|
| `SWPW` | |
|
||||||
|
| `SXTB` | |
|
||||||
|
| `SXTBW` | |
|
||||||
|
| `SXTH` | |
|
||||||
|
| `SXTHW` | |
|
||||||
|
| `SXTW` | |
|
||||||
|
| `SYS` | |
|
||||||
|
| `SYSL` | |
|
||||||
|
| `TBNZ` | Compare/test and branch |
|
||||||
|
| `TBZ` | Compare/test and branch |
|
||||||
|
| `TLBI` | |
|
||||||
|
| `TST` | TST (64-bit) |
|
||||||
|
| `TSTW` | TST (32-bit) |
|
||||||
|
| `UBFIZ` | |
|
||||||
|
| `UBFIZW` | |
|
||||||
|
| `UBFM` | Bitfield extract |
|
||||||
|
| `UBFMW` | |
|
||||||
|
| `UBFX` | Bitfield extract |
|
||||||
|
| `UBFXW` | |
|
||||||
|
| `UCVTFD` | |
|
||||||
|
| `UCVTFS` | |
|
||||||
|
| `UCVTFWD` | |
|
||||||
|
| `UCVTFWS` | |
|
||||||
|
| `UDIV` | Divide |
|
||||||
|
| `UDIVW` | Divide |
|
||||||
|
| `UMADDL` | Multiply / multiply-accumulate |
|
||||||
|
| `UMNEGL` | |
|
||||||
|
| `UMSUBL` | Multiply / multiply-accumulate |
|
||||||
|
| `UMULH` | Multiply / multiply-accumulate |
|
||||||
|
| `UMULL` | Multiply / multiply-accumulate |
|
||||||
|
| `UREM` | |
|
||||||
|
| `UREMW` | |
|
||||||
|
| `UXTB` | |
|
||||||
|
| `UXTBW` | |
|
||||||
|
| `UXTH` | |
|
||||||
|
| `UXTHW` | |
|
||||||
|
| `UXTW` | |
|
||||||
|
| `VADD` | NEON SIMD vector operation |
|
||||||
|
| `VADDP` | |
|
||||||
|
| `VADDV` | NEON SIMD vector operation |
|
||||||
|
| `VAND` | NEON SIMD vector operation |
|
||||||
|
| `VBCAX` | Three-way XOR / rotate crypto vector operation |
|
||||||
|
| `VBIF` | NEON SIMD vector operation |
|
||||||
|
| `VBIT` | |
|
||||||
|
| `VBSL` | NEON SIMD vector operation |
|
||||||
|
| `VCMEQ` | |
|
||||||
|
| `VCMTST` | |
|
||||||
|
| `VCNT` | NEON SIMD vector operation |
|
||||||
|
| `VDUP` | NEON SIMD vector operation |
|
||||||
|
| `VEOR` | NEON SIMD vector operation |
|
||||||
|
| `VEOR3` | Three-way XOR / rotate crypto vector operation |
|
||||||
|
| `VEXT` | NEON SIMD vector operation |
|
||||||
|
| `VFMLA` | NEON SIMD vector operation |
|
||||||
|
| `VFMLS` | NEON SIMD vector operation |
|
||||||
|
| `VLD1` | NEON SIMD vector operation |
|
||||||
|
| `VLD1R` | |
|
||||||
|
| `VLD2` | NEON SIMD vector operation |
|
||||||
|
| `VLD2R` | |
|
||||||
|
| `VLD3` | NEON SIMD vector operation |
|
||||||
|
| `VLD3R` | |
|
||||||
|
| `VLD4` | NEON SIMD vector operation |
|
||||||
|
| `VLD4R` | |
|
||||||
|
| `VMOV` | NEON SIMD vector operation |
|
||||||
|
| `VMOVD` | |
|
||||||
|
| `VMOVI` | NEON SIMD vector operation |
|
||||||
|
| `VMOVQ` | NEON SIMD vector operation |
|
||||||
|
| `VMOVS` | |
|
||||||
|
| `VORR` | NEON SIMD vector operation |
|
||||||
|
| `VPMULL` | |
|
||||||
|
| `VPMULL2` | |
|
||||||
|
| `VRAX1` | Three-way XOR / rotate crypto vector operation |
|
||||||
|
| `VRBIT` | |
|
||||||
|
| `VREV16` | NEON SIMD vector operation |
|
||||||
|
| `VREV32` | NEON SIMD vector operation |
|
||||||
|
| `VREV64` | NEON SIMD vector operation |
|
||||||
|
| `VSHL` | NEON SIMD vector operation |
|
||||||
|
| `VSLI` | |
|
||||||
|
| `VSRI` | |
|
||||||
|
| `VST1` | NEON SIMD vector operation |
|
||||||
|
| `VST2` | NEON SIMD vector operation |
|
||||||
|
| `VST3` | NEON SIMD vector operation |
|
||||||
|
| `VST4` | NEON SIMD vector operation |
|
||||||
|
| `VSUB` | NEON SIMD vector operation |
|
||||||
|
| `VTBL` | NEON SIMD vector operation |
|
||||||
|
| `VTBX` | NEON SIMD vector operation |
|
||||||
|
| `VTRN1` | NEON SIMD vector operation |
|
||||||
|
| `VTRN2` | NEON SIMD vector operation |
|
||||||
|
| `VUADDLV` | |
|
||||||
|
| `VUADDW` | |
|
||||||
|
| `VUADDW2` | |
|
||||||
|
| `VUMAX` | |
|
||||||
|
| `VUMIN` | |
|
||||||
|
| `VUSHLL` | |
|
||||||
|
| `VUSHLL2` | |
|
||||||
|
| `VUSHR` | NEON SIMD vector operation |
|
||||||
|
| `VUSRA` | |
|
||||||
|
| `VUXTL` | |
|
||||||
|
| `VUXTL2` | |
|
||||||
|
| `VUZP1` | NEON SIMD vector operation |
|
||||||
|
| `VUZP2` | NEON SIMD vector operation |
|
||||||
|
| `VXAR` | Three-way XOR / rotate crypto vector operation |
|
||||||
|
| `VZIP1` | NEON SIMD vector operation |
|
||||||
|
| `VZIP2` | NEON SIMD vector operation |
|
||||||
|
| `WFE` | |
|
||||||
|
| `WFI` | |
|
||||||
|
| `WORD` | |
|
||||||
|
| `YIELD` | |
|
||||||
|
| `B` | Unconditional branch |
|
||||||
|
| `BL` | Branch with link |
|
||||||
|
|
||||||
|
Recognised: 554 mnemonics.
|
||||||
@@ -0,0 +1,830 @@
|
|||||||
|
# LoongArch 64: instruction inventory
|
||||||
|
|
||||||
|
Generated by gasm-devkit's `_gen` from the Go toolchain's instruction table
|
||||||
|
(`cmd/internal/obj/loong64/anames.go`, go1.27.1); DO NOT EDIT. This page lists every mnemonic
|
||||||
|
`go tool asm` accepts on this target, which is the upper bound of the
|
||||||
|
language on it: a name absent here is not an instruction of the target,
|
||||||
|
and a name present here may still be one gasm's encoder cannot emit yet.
|
||||||
|
|
||||||
|
The inventory carries no per-mnemonic encoder column: on this target
|
||||||
|
encodability is decided per operand shape, and the live measured
|
||||||
|
coverage is reported by `gasm audit-instructions`.
|
||||||
|
|
||||||
|
| Mnemonic | Notes |
|
||||||
|
|---|---|
|
||||||
|
| `CALL` | |
|
||||||
|
| `DUFFCOPY` | |
|
||||||
|
| `DUFFZERO` | |
|
||||||
|
| `END` | |
|
||||||
|
| `FUNCDATA` | |
|
||||||
|
| `GETCALLERPC` | |
|
||||||
|
| `JMP` | |
|
||||||
|
| `NOP` | No operation |
|
||||||
|
| `PCALIGN` | |
|
||||||
|
| `PCALIGNMAX` | |
|
||||||
|
| `PCDATA` | |
|
||||||
|
| `RET` | Return |
|
||||||
|
| `TEXT` | |
|
||||||
|
| `UNDEF` | |
|
||||||
|
| `ABSD` | |
|
||||||
|
| `ABSF` | |
|
||||||
|
| `ADD` | Integer add (word) |
|
||||||
|
| `ADDD` | Add doubleword |
|
||||||
|
| `ADDF` | |
|
||||||
|
| `ADDV` | |
|
||||||
|
| `ADDV16` | |
|
||||||
|
| `ADDVU` | |
|
||||||
|
| `ADDW` | Add word |
|
||||||
|
| `ALSLV` | |
|
||||||
|
| `ALSLW` | |
|
||||||
|
| `ALSLWU` | |
|
||||||
|
| `AMADDDBV` | |
|
||||||
|
| `AMADDDBW` | |
|
||||||
|
| `AMADDV` | |
|
||||||
|
| `AMADDW` | |
|
||||||
|
| `AMANDDBV` | |
|
||||||
|
| `AMANDDBW` | |
|
||||||
|
| `AMANDV` | |
|
||||||
|
| `AMANDW` | |
|
||||||
|
| `AMCASB` | |
|
||||||
|
| `AMCASDBB` | |
|
||||||
|
| `AMCASDBH` | |
|
||||||
|
| `AMCASDBV` | |
|
||||||
|
| `AMCASDBW` | |
|
||||||
|
| `AMCASH` | |
|
||||||
|
| `AMCASV` | |
|
||||||
|
| `AMCASW` | |
|
||||||
|
| `AMMAXDBV` | |
|
||||||
|
| `AMMAXDBVU` | |
|
||||||
|
| `AMMAXDBW` | |
|
||||||
|
| `AMMAXDBWU` | |
|
||||||
|
| `AMMAXV` | |
|
||||||
|
| `AMMAXVU` | |
|
||||||
|
| `AMMAXW` | |
|
||||||
|
| `AMMAXWU` | |
|
||||||
|
| `AMMINDBV` | |
|
||||||
|
| `AMMINDBVU` | |
|
||||||
|
| `AMMINDBW` | |
|
||||||
|
| `AMMINDBWU` | |
|
||||||
|
| `AMMINV` | |
|
||||||
|
| `AMMINVU` | |
|
||||||
|
| `AMMINW` | |
|
||||||
|
| `AMMINWU` | |
|
||||||
|
| `AMORDBV` | |
|
||||||
|
| `AMORDBW` | |
|
||||||
|
| `AMORV` | |
|
||||||
|
| `AMORW` | |
|
||||||
|
| `AMSWAPB` | |
|
||||||
|
| `AMSWAPDBB` | |
|
||||||
|
| `AMSWAPDBH` | |
|
||||||
|
| `AMSWAPDBV` | |
|
||||||
|
| `AMSWAPDBW` | |
|
||||||
|
| `AMSWAPH` | |
|
||||||
|
| `AMSWAPV` | |
|
||||||
|
| `AMSWAPW` | |
|
||||||
|
| `AMXORDBV` | |
|
||||||
|
| `AMXORDBW` | |
|
||||||
|
| `AMXORV` | |
|
||||||
|
| `AMXORW` | |
|
||||||
|
| `AND` | Bitwise AND |
|
||||||
|
| `ANDN` | |
|
||||||
|
| `BEQ` | Branch if equal |
|
||||||
|
| `BFPF` | |
|
||||||
|
| `BFPT` | |
|
||||||
|
| `BGE` | Branch if greater or equal |
|
||||||
|
| `BGEU` | Branch if greater or equal unsigned |
|
||||||
|
| `BGEZ` | |
|
||||||
|
| `BGTZ` | |
|
||||||
|
| `BITREV4B` | |
|
||||||
|
| `BITREV8B` | |
|
||||||
|
| `BITREVV` | |
|
||||||
|
| `BITREVW` | |
|
||||||
|
| `BLEZ` | |
|
||||||
|
| `BLT` | Branch if less than |
|
||||||
|
| `BLTU` | Branch if less than unsigned |
|
||||||
|
| `BLTZ` | |
|
||||||
|
| `BNE` | Branch if not equal |
|
||||||
|
| `BREAK` | Breakpoint |
|
||||||
|
| `BSTRINSV` | |
|
||||||
|
| `BSTRINSW` | |
|
||||||
|
| `BSTRPICKV` | |
|
||||||
|
| `BSTRPICKW` | |
|
||||||
|
| `CLOV` | |
|
||||||
|
| `CLOW` | |
|
||||||
|
| `CLZV` | |
|
||||||
|
| `CLZW` | |
|
||||||
|
| `CMPEQD` | |
|
||||||
|
| `CMPEQF` | |
|
||||||
|
| `CMPGED` | |
|
||||||
|
| `CMPGEF` | |
|
||||||
|
| `CMPGTD` | |
|
||||||
|
| `CMPGTF` | |
|
||||||
|
| `CPUCFG` | |
|
||||||
|
| `CRCCWBW` | |
|
||||||
|
| `CRCCWHW` | |
|
||||||
|
| `CRCCWVW` | |
|
||||||
|
| `CRCCWWW` | |
|
||||||
|
| `CRCWBW` | |
|
||||||
|
| `CRCWHW` | |
|
||||||
|
| `CRCWVW` | |
|
||||||
|
| `CRCWWW` | |
|
||||||
|
| `CTOV` | |
|
||||||
|
| `CTOW` | |
|
||||||
|
| `CTZV` | |
|
||||||
|
| `CTZW` | |
|
||||||
|
| `DBAR` | Barrier |
|
||||||
|
| `DIV` | Divide (word) |
|
||||||
|
| `DIVD` | Divide doubleword |
|
||||||
|
| `DIVF` | |
|
||||||
|
| `DIVU` | |
|
||||||
|
| `DIVV` | |
|
||||||
|
| `DIVVU` | |
|
||||||
|
| `DIVW` | Divide word |
|
||||||
|
| `DIVWU` | |
|
||||||
|
| `EXTWB` | |
|
||||||
|
| `EXTWH` | |
|
||||||
|
| `FCLASSD` | |
|
||||||
|
| `FCLASSF` | |
|
||||||
|
| `FCOPYSGD` | |
|
||||||
|
| `FCOPYSGF` | |
|
||||||
|
| `FFINTDV` | |
|
||||||
|
| `FFINTDW` | |
|
||||||
|
| `FFINTFV` | |
|
||||||
|
| `FFINTFW` | |
|
||||||
|
| `FLOGBD` | |
|
||||||
|
| `FLOGBF` | |
|
||||||
|
| `FMADDD` | |
|
||||||
|
| `FMADDF` | |
|
||||||
|
| `FMAXAD` | |
|
||||||
|
| `FMAXAF` | |
|
||||||
|
| `FMAXD` | |
|
||||||
|
| `FMAXF` | |
|
||||||
|
| `FMINAD` | |
|
||||||
|
| `FMINAF` | |
|
||||||
|
| `FMIND` | |
|
||||||
|
| `FMINF` | |
|
||||||
|
| `FMSUBD` | |
|
||||||
|
| `FMSUBF` | |
|
||||||
|
| `FNMADDD` | |
|
||||||
|
| `FNMADDF` | |
|
||||||
|
| `FNMSUBD` | |
|
||||||
|
| `FNMSUBF` | |
|
||||||
|
| `FSCALEBD` | |
|
||||||
|
| `FSCALEBF` | |
|
||||||
|
| `FSEL` | |
|
||||||
|
| `FTINTRMVD` | |
|
||||||
|
| `FTINTRMVF` | |
|
||||||
|
| `FTINTRMWD` | |
|
||||||
|
| `FTINTRMWF` | |
|
||||||
|
| `FTINTRNEVD` | |
|
||||||
|
| `FTINTRNEVF` | |
|
||||||
|
| `FTINTRNEWD` | |
|
||||||
|
| `FTINTRNEWF` | |
|
||||||
|
| `FTINTRPVD` | |
|
||||||
|
| `FTINTRPVF` | |
|
||||||
|
| `FTINTRPWD` | |
|
||||||
|
| `FTINTRPWF` | |
|
||||||
|
| `FTINTRZVD` | |
|
||||||
|
| `FTINTRZVF` | |
|
||||||
|
| `FTINTRZWD` | |
|
||||||
|
| `FTINTRZWF` | |
|
||||||
|
| `FTINTVD` | |
|
||||||
|
| `FTINTVF` | |
|
||||||
|
| `FTINTWD` | |
|
||||||
|
| `FTINTWF` | |
|
||||||
|
| `JIRL` | Jump indirect with link |
|
||||||
|
| `LL` | |
|
||||||
|
| `LLV` | |
|
||||||
|
| `LU12IW` | |
|
||||||
|
| `LU32ID` | |
|
||||||
|
| `LU52ID` | |
|
||||||
|
| `LUI` | |
|
||||||
|
| `MASKEQZ` | |
|
||||||
|
| `MASKNEZ` | |
|
||||||
|
| `MOVB` | |
|
||||||
|
| `MOVBU` | |
|
||||||
|
| `MOVD` | |
|
||||||
|
| `MOVDF` | |
|
||||||
|
| `MOVDV` | |
|
||||||
|
| `MOVDW` | |
|
||||||
|
| `MOVF` | |
|
||||||
|
| `MOVFD` | |
|
||||||
|
| `MOVFV` | |
|
||||||
|
| `MOVFW` | |
|
||||||
|
| `MOVH` | |
|
||||||
|
| `MOVHU` | |
|
||||||
|
| `MOVV` | |
|
||||||
|
| `MOVVD` | |
|
||||||
|
| `MOVVF` | |
|
||||||
|
| `MOVVP` | |
|
||||||
|
| `MOVW` | |
|
||||||
|
| `MOVWD` | |
|
||||||
|
| `MOVWF` | |
|
||||||
|
| `MOVWP` | |
|
||||||
|
| `MOVWU` | |
|
||||||
|
| `MUL` | Multiply (word) |
|
||||||
|
| `MULD` | Multiply doubleword |
|
||||||
|
| `MULF` | |
|
||||||
|
| `MULH` | |
|
||||||
|
| `MULHU` | |
|
||||||
|
| `MULHV` | |
|
||||||
|
| `MULHVU` | |
|
||||||
|
| `MULV` | |
|
||||||
|
| `MULVU` | |
|
||||||
|
| `MULW` | Multiply word |
|
||||||
|
| `MULWVW` | |
|
||||||
|
| `MULWVWU` | |
|
||||||
|
| `NEGD` | |
|
||||||
|
| `NEGF` | |
|
||||||
|
| `NEGV` | |
|
||||||
|
| `NEGW` | |
|
||||||
|
| `NOOP` | |
|
||||||
|
| `NOR` | Bitwise NOR |
|
||||||
|
| `OR` | Bitwise OR |
|
||||||
|
| `ORN` | |
|
||||||
|
| `PCADDU12I` | |
|
||||||
|
| `PCALAU12I` | |
|
||||||
|
| `PRELD` | |
|
||||||
|
| `PRELDX` | |
|
||||||
|
| `RDTIMED` | |
|
||||||
|
| `RDTIMEHW` | |
|
||||||
|
| `RDTIMELW` | |
|
||||||
|
| `REM` | |
|
||||||
|
| `REMU` | |
|
||||||
|
| `REMV` | |
|
||||||
|
| `REMVU` | |
|
||||||
|
| `REMW` | |
|
||||||
|
| `REMWU` | |
|
||||||
|
| `REVB2H` | |
|
||||||
|
| `REVB2W` | |
|
||||||
|
| `REVB4H` | |
|
||||||
|
| `REVBV` | |
|
||||||
|
| `REVH2W` | |
|
||||||
|
| `REVHV` | |
|
||||||
|
| `RFE` | |
|
||||||
|
| `ROTR` | Rotate right |
|
||||||
|
| `ROTRV` | |
|
||||||
|
| `SC` | |
|
||||||
|
| `SCV` | |
|
||||||
|
| `SGT` | |
|
||||||
|
| `SGTU` | |
|
||||||
|
| `SLL` | Shift left logical |
|
||||||
|
| `SLLV` | |
|
||||||
|
| `SQRTD` | |
|
||||||
|
| `SQRTF` | |
|
||||||
|
| `SRA` | Shift right arithmetic |
|
||||||
|
| `SRAV` | |
|
||||||
|
| `SRL` | Shift right logical |
|
||||||
|
| `SRLV` | |
|
||||||
|
| `SUB` | Subtract (word) |
|
||||||
|
| `SUBD` | Subtract doubleword |
|
||||||
|
| `SUBF` | |
|
||||||
|
| `SUBV` | |
|
||||||
|
| `SUBVU` | |
|
||||||
|
| `SUBW` | Subtract word |
|
||||||
|
| `SYSCALL` | System call |
|
||||||
|
| `TEQ` | |
|
||||||
|
| `TNE` | |
|
||||||
|
| `TRUNCDV` | |
|
||||||
|
| `TRUNCDW` | |
|
||||||
|
| `TRUNCFV` | |
|
||||||
|
| `TRUNCFW` | |
|
||||||
|
| `VADDB` | |
|
||||||
|
| `VADDBU` | |
|
||||||
|
| `VADDD` | |
|
||||||
|
| `VADDF` | |
|
||||||
|
| `VADDH` | |
|
||||||
|
| `VADDHU` | |
|
||||||
|
| `VADDQ` | |
|
||||||
|
| `VADDV` | |
|
||||||
|
| `VADDVU` | |
|
||||||
|
| `VADDW` | |
|
||||||
|
| `VADDWEVHB` | |
|
||||||
|
| `VADDWEVHBU` | |
|
||||||
|
| `VADDWEVQV` | |
|
||||||
|
| `VADDWEVQVU` | |
|
||||||
|
| `VADDWEVVW` | |
|
||||||
|
| `VADDWEVVWU` | |
|
||||||
|
| `VADDWEVWH` | |
|
||||||
|
| `VADDWEVWHU` | |
|
||||||
|
| `VADDWODHB` | |
|
||||||
|
| `VADDWODHBU` | |
|
||||||
|
| `VADDWODQV` | |
|
||||||
|
| `VADDWODQVU` | |
|
||||||
|
| `VADDWODVW` | |
|
||||||
|
| `VADDWODVWU` | |
|
||||||
|
| `VADDWODWH` | |
|
||||||
|
| `VADDWODWHU` | |
|
||||||
|
| `VADDWU` | |
|
||||||
|
| `VANDB` | |
|
||||||
|
| `VANDNV` | |
|
||||||
|
| `VANDV` | |
|
||||||
|
| `VBITCLRB` | |
|
||||||
|
| `VBITCLRH` | |
|
||||||
|
| `VBITCLRV` | |
|
||||||
|
| `VBITCLRW` | |
|
||||||
|
| `VBITREVB` | |
|
||||||
|
| `VBITREVH` | |
|
||||||
|
| `VBITREVV` | |
|
||||||
|
| `VBITREVW` | |
|
||||||
|
| `VBITSETB` | |
|
||||||
|
| `VBITSETH` | |
|
||||||
|
| `VBITSETV` | |
|
||||||
|
| `VBITSETW` | |
|
||||||
|
| `VDIVB` | |
|
||||||
|
| `VDIVBU` | |
|
||||||
|
| `VDIVD` | |
|
||||||
|
| `VDIVF` | |
|
||||||
|
| `VDIVH` | |
|
||||||
|
| `VDIVHU` | |
|
||||||
|
| `VDIVV` | |
|
||||||
|
| `VDIVVU` | |
|
||||||
|
| `VDIVW` | |
|
||||||
|
| `VDIVWU` | |
|
||||||
|
| `VEXTRINSB` | |
|
||||||
|
| `VEXTRINSH` | |
|
||||||
|
| `VEXTRINSV` | |
|
||||||
|
| `VEXTRINSW` | |
|
||||||
|
| `VFCLASSD` | |
|
||||||
|
| `VFCLASSF` | |
|
||||||
|
| `VFRECIPD` | |
|
||||||
|
| `VFRECIPF` | |
|
||||||
|
| `VFRINTD` | |
|
||||||
|
| `VFRINTF` | |
|
||||||
|
| `VFRINTRMD` | |
|
||||||
|
| `VFRINTRMF` | |
|
||||||
|
| `VFRINTRNED` | |
|
||||||
|
| `VFRINTRNEF` | |
|
||||||
|
| `VFRINTRPD` | |
|
||||||
|
| `VFRINTRPF` | |
|
||||||
|
| `VFRINTRZD` | |
|
||||||
|
| `VFRINTRZF` | |
|
||||||
|
| `VFRSQRTD` | |
|
||||||
|
| `VFRSQRTF` | |
|
||||||
|
| `VFSQRTD` | |
|
||||||
|
| `VFSQRTF` | |
|
||||||
|
| `VILVHB` | |
|
||||||
|
| `VILVHH` | |
|
||||||
|
| `VILVHV` | |
|
||||||
|
| `VILVHW` | |
|
||||||
|
| `VILVLB` | |
|
||||||
|
| `VILVLH` | |
|
||||||
|
| `VILVLV` | |
|
||||||
|
| `VILVLW` | |
|
||||||
|
| `VMADDB` | |
|
||||||
|
| `VMADDH` | |
|
||||||
|
| `VMADDV` | |
|
||||||
|
| `VMADDW` | |
|
||||||
|
| `VMADDWEVHB` | |
|
||||||
|
| `VMADDWEVHBU` | |
|
||||||
|
| `VMADDWEVHBUB` | |
|
||||||
|
| `VMADDWEVQV` | |
|
||||||
|
| `VMADDWEVQVU` | |
|
||||||
|
| `VMADDWEVQVUV` | |
|
||||||
|
| `VMADDWEVVW` | |
|
||||||
|
| `VMADDWEVVWU` | |
|
||||||
|
| `VMADDWEVVWUW` | |
|
||||||
|
| `VMADDWEVWH` | |
|
||||||
|
| `VMADDWEVWHU` | |
|
||||||
|
| `VMADDWEVWHUH` | |
|
||||||
|
| `VMADDWODHB` | |
|
||||||
|
| `VMADDWODHBU` | |
|
||||||
|
| `VMADDWODHBUB` | |
|
||||||
|
| `VMADDWODQV` | |
|
||||||
|
| `VMADDWODQVU` | |
|
||||||
|
| `VMADDWODQVUV` | |
|
||||||
|
| `VMADDWODVW` | |
|
||||||
|
| `VMADDWODVWU` | |
|
||||||
|
| `VMADDWODVWUW` | |
|
||||||
|
| `VMADDWODWH` | |
|
||||||
|
| `VMADDWODWHU` | |
|
||||||
|
| `VMADDWODWHUH` | |
|
||||||
|
| `VMODB` | |
|
||||||
|
| `VMODBU` | |
|
||||||
|
| `VMODH` | |
|
||||||
|
| `VMODHU` | |
|
||||||
|
| `VMODV` | |
|
||||||
|
| `VMODVU` | |
|
||||||
|
| `VMODW` | |
|
||||||
|
| `VMODWU` | |
|
||||||
|
| `VMOVQ` | |
|
||||||
|
| `VMSUBB` | |
|
||||||
|
| `VMSUBH` | |
|
||||||
|
| `VMSUBV` | |
|
||||||
|
| `VMSUBW` | |
|
||||||
|
| `VMUHB` | |
|
||||||
|
| `VMUHBU` | |
|
||||||
|
| `VMUHH` | |
|
||||||
|
| `VMUHHU` | |
|
||||||
|
| `VMUHV` | |
|
||||||
|
| `VMUHVU` | |
|
||||||
|
| `VMUHW` | |
|
||||||
|
| `VMUHWU` | |
|
||||||
|
| `VMULB` | |
|
||||||
|
| `VMULD` | |
|
||||||
|
| `VMULF` | |
|
||||||
|
| `VMULH` | |
|
||||||
|
| `VMULV` | |
|
||||||
|
| `VMULW` | |
|
||||||
|
| `VMULWEVHB` | |
|
||||||
|
| `VMULWEVHBU` | |
|
||||||
|
| `VMULWEVHBUB` | |
|
||||||
|
| `VMULWEVQV` | |
|
||||||
|
| `VMULWEVQVU` | |
|
||||||
|
| `VMULWEVQVUV` | |
|
||||||
|
| `VMULWEVVW` | |
|
||||||
|
| `VMULWEVVWU` | |
|
||||||
|
| `VMULWEVVWUW` | |
|
||||||
|
| `VMULWEVWH` | |
|
||||||
|
| `VMULWEVWHU` | |
|
||||||
|
| `VMULWEVWHUH` | |
|
||||||
|
| `VMULWODHB` | |
|
||||||
|
| `VMULWODHBU` | |
|
||||||
|
| `VMULWODHBUB` | |
|
||||||
|
| `VMULWODQV` | |
|
||||||
|
| `VMULWODQVU` | |
|
||||||
|
| `VMULWODQVUV` | |
|
||||||
|
| `VMULWODVW` | |
|
||||||
|
| `VMULWODVWU` | |
|
||||||
|
| `VMULWODVWUW` | |
|
||||||
|
| `VMULWODWH` | |
|
||||||
|
| `VMULWODWHU` | |
|
||||||
|
| `VMULWODWHUH` | |
|
||||||
|
| `VNEGB` | |
|
||||||
|
| `VNEGH` | |
|
||||||
|
| `VNEGV` | |
|
||||||
|
| `VNEGW` | |
|
||||||
|
| `VNORB` | |
|
||||||
|
| `VNORV` | |
|
||||||
|
| `VORB` | |
|
||||||
|
| `VORNV` | |
|
||||||
|
| `VORV` | |
|
||||||
|
| `VPCNTB` | |
|
||||||
|
| `VPCNTH` | |
|
||||||
|
| `VPCNTV` | |
|
||||||
|
| `VPCNTW` | |
|
||||||
|
| `VPERMIW` | |
|
||||||
|
| `VROTRB` | |
|
||||||
|
| `VROTRH` | |
|
||||||
|
| `VROTRV` | |
|
||||||
|
| `VROTRW` | |
|
||||||
|
| `VSADDB` | |
|
||||||
|
| `VSADDBU` | |
|
||||||
|
| `VSADDH` | |
|
||||||
|
| `VSADDHU` | |
|
||||||
|
| `VSADDV` | |
|
||||||
|
| `VSADDVU` | |
|
||||||
|
| `VSADDW` | |
|
||||||
|
| `VSADDWU` | |
|
||||||
|
| `VSEQB` | |
|
||||||
|
| `VSEQH` | |
|
||||||
|
| `VSEQV` | |
|
||||||
|
| `VSEQW` | |
|
||||||
|
| `VSETALLNEB` | |
|
||||||
|
| `VSETALLNEH` | |
|
||||||
|
| `VSETALLNEV` | |
|
||||||
|
| `VSETALLNEW` | |
|
||||||
|
| `VSETANYEQB` | |
|
||||||
|
| `VSETANYEQH` | |
|
||||||
|
| `VSETANYEQV` | |
|
||||||
|
| `VSETANYEQW` | |
|
||||||
|
| `VSETEQV` | |
|
||||||
|
| `VSETNEV` | |
|
||||||
|
| `VSHUF4IB` | |
|
||||||
|
| `VSHUF4IH` | |
|
||||||
|
| `VSHUF4IV` | |
|
||||||
|
| `VSHUF4IW` | |
|
||||||
|
| `VSHUFB` | |
|
||||||
|
| `VSHUFH` | |
|
||||||
|
| `VSHUFV` | |
|
||||||
|
| `VSHUFW` | |
|
||||||
|
| `VSLLB` | |
|
||||||
|
| `VSLLH` | |
|
||||||
|
| `VSLLV` | |
|
||||||
|
| `VSLLW` | |
|
||||||
|
| `VSLTB` | |
|
||||||
|
| `VSLTBU` | |
|
||||||
|
| `VSLTH` | |
|
||||||
|
| `VSLTHU` | |
|
||||||
|
| `VSLTV` | |
|
||||||
|
| `VSLTVU` | |
|
||||||
|
| `VSLTW` | |
|
||||||
|
| `VSLTWU` | |
|
||||||
|
| `VSRAB` | |
|
||||||
|
| `VSRAH` | |
|
||||||
|
| `VSRAV` | |
|
||||||
|
| `VSRAW` | |
|
||||||
|
| `VSRLB` | |
|
||||||
|
| `VSRLH` | |
|
||||||
|
| `VSRLV` | |
|
||||||
|
| `VSRLW` | |
|
||||||
|
| `VSSUBB` | |
|
||||||
|
| `VSSUBBU` | |
|
||||||
|
| `VSSUBH` | |
|
||||||
|
| `VSSUBHU` | |
|
||||||
|
| `VSSUBV` | |
|
||||||
|
| `VSSUBVU` | |
|
||||||
|
| `VSSUBW` | |
|
||||||
|
| `VSSUBWU` | |
|
||||||
|
| `VSUBB` | |
|
||||||
|
| `VSUBBU` | |
|
||||||
|
| `VSUBD` | |
|
||||||
|
| `VSUBF` | |
|
||||||
|
| `VSUBH` | |
|
||||||
|
| `VSUBHU` | |
|
||||||
|
| `VSUBQ` | |
|
||||||
|
| `VSUBV` | |
|
||||||
|
| `VSUBVU` | |
|
||||||
|
| `VSUBW` | |
|
||||||
|
| `VSUBWEVHB` | |
|
||||||
|
| `VSUBWEVHBU` | |
|
||||||
|
| `VSUBWEVQV` | |
|
||||||
|
| `VSUBWEVQVU` | |
|
||||||
|
| `VSUBWEVVW` | |
|
||||||
|
| `VSUBWEVVWU` | |
|
||||||
|
| `VSUBWEVWH` | |
|
||||||
|
| `VSUBWEVWHU` | |
|
||||||
|
| `VSUBWODHB` | |
|
||||||
|
| `VSUBWODHBU` | |
|
||||||
|
| `VSUBWODQV` | |
|
||||||
|
| `VSUBWODQVU` | |
|
||||||
|
| `VSUBWODVW` | |
|
||||||
|
| `VSUBWODVWU` | |
|
||||||
|
| `VSUBWODWH` | |
|
||||||
|
| `VSUBWODWHU` | |
|
||||||
|
| `VSUBWU` | |
|
||||||
|
| `VXORB` | |
|
||||||
|
| `VXORV` | |
|
||||||
|
| `WORD` | |
|
||||||
|
| `XOR` | Bitwise XOR |
|
||||||
|
| `XVADDB` | |
|
||||||
|
| `XVADDBU` | |
|
||||||
|
| `XVADDD` | |
|
||||||
|
| `XVADDF` | |
|
||||||
|
| `XVADDH` | |
|
||||||
|
| `XVADDHU` | |
|
||||||
|
| `XVADDQ` | |
|
||||||
|
| `XVADDV` | |
|
||||||
|
| `XVADDVU` | |
|
||||||
|
| `XVADDW` | |
|
||||||
|
| `XVADDWEVHB` | |
|
||||||
|
| `XVADDWEVHBU` | |
|
||||||
|
| `XVADDWEVQV` | |
|
||||||
|
| `XVADDWEVQVU` | |
|
||||||
|
| `XVADDWEVVW` | |
|
||||||
|
| `XVADDWEVVWU` | |
|
||||||
|
| `XVADDWEVWH` | |
|
||||||
|
| `XVADDWEVWHU` | |
|
||||||
|
| `XVADDWODHB` | |
|
||||||
|
| `XVADDWODHBU` | |
|
||||||
|
| `XVADDWODQV` | |
|
||||||
|
| `XVADDWODQVU` | |
|
||||||
|
| `XVADDWODVW` | |
|
||||||
|
| `XVADDWODVWU` | |
|
||||||
|
| `XVADDWODWH` | |
|
||||||
|
| `XVADDWODWHU` | |
|
||||||
|
| `XVADDWU` | |
|
||||||
|
| `XVANDB` | |
|
||||||
|
| `XVANDNV` | |
|
||||||
|
| `XVANDV` | |
|
||||||
|
| `XVBITCLRB` | |
|
||||||
|
| `XVBITCLRH` | |
|
||||||
|
| `XVBITCLRV` | |
|
||||||
|
| `XVBITCLRW` | |
|
||||||
|
| `XVBITREVB` | |
|
||||||
|
| `XVBITREVH` | |
|
||||||
|
| `XVBITREVV` | |
|
||||||
|
| `XVBITREVW` | |
|
||||||
|
| `XVBITSETB` | |
|
||||||
|
| `XVBITSETH` | |
|
||||||
|
| `XVBITSETV` | |
|
||||||
|
| `XVBITSETW` | |
|
||||||
|
| `XVDIVB` | |
|
||||||
|
| `XVDIVBU` | |
|
||||||
|
| `XVDIVD` | |
|
||||||
|
| `XVDIVF` | |
|
||||||
|
| `XVDIVH` | |
|
||||||
|
| `XVDIVHU` | |
|
||||||
|
| `XVDIVV` | |
|
||||||
|
| `XVDIVVU` | |
|
||||||
|
| `XVDIVW` | |
|
||||||
|
| `XVDIVWU` | |
|
||||||
|
| `XVEXTRINSB` | |
|
||||||
|
| `XVEXTRINSH` | |
|
||||||
|
| `XVEXTRINSV` | |
|
||||||
|
| `XVEXTRINSW` | |
|
||||||
|
| `XVFCLASSD` | |
|
||||||
|
| `XVFCLASSF` | |
|
||||||
|
| `XVFRECIPD` | |
|
||||||
|
| `XVFRECIPF` | |
|
||||||
|
| `XVFRINTD` | |
|
||||||
|
| `XVFRINTF` | |
|
||||||
|
| `XVFRINTRMD` | |
|
||||||
|
| `XVFRINTRMF` | |
|
||||||
|
| `XVFRINTRNED` | |
|
||||||
|
| `XVFRINTRNEF` | |
|
||||||
|
| `XVFRINTRPD` | |
|
||||||
|
| `XVFRINTRPF` | |
|
||||||
|
| `XVFRINTRZD` | |
|
||||||
|
| `XVFRINTRZF` | |
|
||||||
|
| `XVFRSQRTD` | |
|
||||||
|
| `XVFRSQRTF` | |
|
||||||
|
| `XVFSQRTD` | |
|
||||||
|
| `XVFSQRTF` | |
|
||||||
|
| `XVILVHB` | |
|
||||||
|
| `XVILVHH` | |
|
||||||
|
| `XVILVHV` | |
|
||||||
|
| `XVILVHW` | |
|
||||||
|
| `XVILVLB` | |
|
||||||
|
| `XVILVLH` | |
|
||||||
|
| `XVILVLV` | |
|
||||||
|
| `XVILVLW` | |
|
||||||
|
| `XVMADDB` | |
|
||||||
|
| `XVMADDH` | |
|
||||||
|
| `XVMADDV` | |
|
||||||
|
| `XVMADDW` | |
|
||||||
|
| `XVMADDWEVHB` | |
|
||||||
|
| `XVMADDWEVHBU` | |
|
||||||
|
| `XVMADDWEVHBUB` | |
|
||||||
|
| `XVMADDWEVQV` | |
|
||||||
|
| `XVMADDWEVQVU` | |
|
||||||
|
| `XVMADDWEVQVUV` | |
|
||||||
|
| `XVMADDWEVVW` | |
|
||||||
|
| `XVMADDWEVVWU` | |
|
||||||
|
| `XVMADDWEVVWUW` | |
|
||||||
|
| `XVMADDWEVWH` | |
|
||||||
|
| `XVMADDWEVWHU` | |
|
||||||
|
| `XVMADDWEVWHUH` | |
|
||||||
|
| `XVMADDWODHB` | |
|
||||||
|
| `XVMADDWODHBU` | |
|
||||||
|
| `XVMADDWODHBUB` | |
|
||||||
|
| `XVMADDWODQV` | |
|
||||||
|
| `XVMADDWODQVU` | |
|
||||||
|
| `XVMADDWODQVUV` | |
|
||||||
|
| `XVMADDWODVW` | |
|
||||||
|
| `XVMADDWODVWU` | |
|
||||||
|
| `XVMADDWODVWUW` | |
|
||||||
|
| `XVMADDWODWH` | |
|
||||||
|
| `XVMADDWODWHU` | |
|
||||||
|
| `XVMADDWODWHUH` | |
|
||||||
|
| `XVMODB` | |
|
||||||
|
| `XVMODBU` | |
|
||||||
|
| `XVMODH` | |
|
||||||
|
| `XVMODHU` | |
|
||||||
|
| `XVMODV` | |
|
||||||
|
| `XVMODVU` | |
|
||||||
|
| `XVMODW` | |
|
||||||
|
| `XVMODWU` | |
|
||||||
|
| `XVMOVQ` | |
|
||||||
|
| `XVMSUBB` | |
|
||||||
|
| `XVMSUBH` | |
|
||||||
|
| `XVMSUBV` | |
|
||||||
|
| `XVMSUBW` | |
|
||||||
|
| `XVMUHB` | |
|
||||||
|
| `XVMUHBU` | |
|
||||||
|
| `XVMUHH` | |
|
||||||
|
| `XVMUHHU` | |
|
||||||
|
| `XVMUHV` | |
|
||||||
|
| `XVMUHVU` | |
|
||||||
|
| `XVMUHW` | |
|
||||||
|
| `XVMUHWU` | |
|
||||||
|
| `XVMULB` | |
|
||||||
|
| `XVMULD` | |
|
||||||
|
| `XVMULF` | |
|
||||||
|
| `XVMULH` | |
|
||||||
|
| `XVMULV` | |
|
||||||
|
| `XVMULW` | |
|
||||||
|
| `XVMULWEVHB` | |
|
||||||
|
| `XVMULWEVHBU` | |
|
||||||
|
| `XVMULWEVHBUB` | |
|
||||||
|
| `XVMULWEVQV` | |
|
||||||
|
| `XVMULWEVQVU` | |
|
||||||
|
| `XVMULWEVQVUV` | |
|
||||||
|
| `XVMULWEVVW` | |
|
||||||
|
| `XVMULWEVVWU` | |
|
||||||
|
| `XVMULWEVVWUW` | |
|
||||||
|
| `XVMULWEVWH` | |
|
||||||
|
| `XVMULWEVWHU` | |
|
||||||
|
| `XVMULWEVWHUH` | |
|
||||||
|
| `XVMULWODHB` | |
|
||||||
|
| `XVMULWODHBU` | |
|
||||||
|
| `XVMULWODHBUB` | |
|
||||||
|
| `XVMULWODQV` | |
|
||||||
|
| `XVMULWODQVU` | |
|
||||||
|
| `XVMULWODQVUV` | |
|
||||||
|
| `XVMULWODVW` | |
|
||||||
|
| `XVMULWODVWU` | |
|
||||||
|
| `XVMULWODVWUW` | |
|
||||||
|
| `XVMULWODWH` | |
|
||||||
|
| `XVMULWODWHU` | |
|
||||||
|
| `XVMULWODWHUH` | |
|
||||||
|
| `XVNEGB` | |
|
||||||
|
| `XVNEGH` | |
|
||||||
|
| `XVNEGV` | |
|
||||||
|
| `XVNEGW` | |
|
||||||
|
| `XVNORB` | |
|
||||||
|
| `XVNORV` | |
|
||||||
|
| `XVORB` | |
|
||||||
|
| `XVORNV` | |
|
||||||
|
| `XVORV` | |
|
||||||
|
| `XVPCNTB` | |
|
||||||
|
| `XVPCNTH` | |
|
||||||
|
| `XVPCNTV` | |
|
||||||
|
| `XVPCNTW` | |
|
||||||
|
| `XVPERMIQ` | |
|
||||||
|
| `XVPERMIV` | |
|
||||||
|
| `XVPERMIW` | |
|
||||||
|
| `XVROTRB` | |
|
||||||
|
| `XVROTRH` | |
|
||||||
|
| `XVROTRV` | |
|
||||||
|
| `XVROTRW` | |
|
||||||
|
| `XVSADDB` | |
|
||||||
|
| `XVSADDBU` | |
|
||||||
|
| `XVSADDH` | |
|
||||||
|
| `XVSADDHU` | |
|
||||||
|
| `XVSADDV` | |
|
||||||
|
| `XVSADDVU` | |
|
||||||
|
| `XVSADDW` | |
|
||||||
|
| `XVSADDWU` | |
|
||||||
|
| `XVSEQB` | |
|
||||||
|
| `XVSEQH` | |
|
||||||
|
| `XVSEQV` | |
|
||||||
|
| `XVSEQW` | |
|
||||||
|
| `XVSETALLNEB` | |
|
||||||
|
| `XVSETALLNEH` | |
|
||||||
|
| `XVSETALLNEV` | |
|
||||||
|
| `XVSETALLNEW` | |
|
||||||
|
| `XVSETANYEQB` | |
|
||||||
|
| `XVSETANYEQH` | |
|
||||||
|
| `XVSETANYEQV` | |
|
||||||
|
| `XVSETANYEQW` | |
|
||||||
|
| `XVSETEQV` | |
|
||||||
|
| `XVSETNEV` | |
|
||||||
|
| `XVSHUF4IB` | |
|
||||||
|
| `XVSHUF4IH` | |
|
||||||
|
| `XVSHUF4IV` | |
|
||||||
|
| `XVSHUF4IW` | |
|
||||||
|
| `XVSHUFB` | |
|
||||||
|
| `XVSHUFH` | |
|
||||||
|
| `XVSHUFV` | |
|
||||||
|
| `XVSHUFW` | |
|
||||||
|
| `XVSLLB` | |
|
||||||
|
| `XVSLLH` | |
|
||||||
|
| `XVSLLV` | |
|
||||||
|
| `XVSLLW` | |
|
||||||
|
| `XVSLTB` | |
|
||||||
|
| `XVSLTBU` | |
|
||||||
|
| `XVSLTH` | |
|
||||||
|
| `XVSLTHU` | |
|
||||||
|
| `XVSLTV` | |
|
||||||
|
| `XVSLTVU` | |
|
||||||
|
| `XVSLTW` | |
|
||||||
|
| `XVSLTWU` | |
|
||||||
|
| `XVSRAB` | |
|
||||||
|
| `XVSRAH` | |
|
||||||
|
| `XVSRAV` | |
|
||||||
|
| `XVSRAW` | |
|
||||||
|
| `XVSRLB` | |
|
||||||
|
| `XVSRLH` | |
|
||||||
|
| `XVSRLV` | |
|
||||||
|
| `XVSRLW` | |
|
||||||
|
| `XVSSUBB` | |
|
||||||
|
| `XVSSUBBU` | |
|
||||||
|
| `XVSSUBH` | |
|
||||||
|
| `XVSSUBHU` | |
|
||||||
|
| `XVSSUBV` | |
|
||||||
|
| `XVSSUBVU` | |
|
||||||
|
| `XVSSUBW` | |
|
||||||
|
| `XVSSUBWU` | |
|
||||||
|
| `XVSUBB` | |
|
||||||
|
| `XVSUBBU` | |
|
||||||
|
| `XVSUBD` | |
|
||||||
|
| `XVSUBF` | |
|
||||||
|
| `XVSUBH` | |
|
||||||
|
| `XVSUBHU` | |
|
||||||
|
| `XVSUBQ` | |
|
||||||
|
| `XVSUBV` | |
|
||||||
|
| `XVSUBVU` | |
|
||||||
|
| `XVSUBW` | |
|
||||||
|
| `XVSUBWEVHB` | |
|
||||||
|
| `XVSUBWEVHBU` | |
|
||||||
|
| `XVSUBWEVQV` | |
|
||||||
|
| `XVSUBWEVQVU` | |
|
||||||
|
| `XVSUBWEVVW` | |
|
||||||
|
| `XVSUBWEVVWU` | |
|
||||||
|
| `XVSUBWEVWH` | |
|
||||||
|
| `XVSUBWEVWHU` | |
|
||||||
|
| `XVSUBWODHB` | |
|
||||||
|
| `XVSUBWODHBU` | |
|
||||||
|
| `XVSUBWODQV` | |
|
||||||
|
| `XVSUBWODQVU` | |
|
||||||
|
| `XVSUBWODVW` | |
|
||||||
|
| `XVSUBWODVWU` | |
|
||||||
|
| `XVSUBWODWH` | |
|
||||||
|
| `XVSUBWODWHU` | |
|
||||||
|
| `XVSUBWU` | |
|
||||||
|
| `XVXORB` | |
|
||||||
|
| `XVXORV` | |
|
||||||
|
| `JAL` | |
|
||||||
|
|
||||||
|
Recognised: 814 mnemonics.
|
||||||
@@ -0,0 +1,991 @@
|
|||||||
|
# RISC-V 64: instruction inventory
|
||||||
|
|
||||||
|
Generated by gasm-devkit's `_gen` from the Go toolchain's instruction table
|
||||||
|
(`cmd/internal/obj/riscv/anames.go`, go1.27.1); DO NOT EDIT. This page lists every mnemonic
|
||||||
|
`go tool asm` accepts on this target, which is the upper bound of the
|
||||||
|
language on it: a name absent here is not an instruction of the target,
|
||||||
|
and a name present here may still be one gasm's encoder cannot emit yet.
|
||||||
|
|
||||||
|
The inventory carries no per-mnemonic encoder column: on this target
|
||||||
|
encodability is decided per operand shape, and the live measured
|
||||||
|
coverage is reported by `gasm audit-instructions`.
|
||||||
|
|
||||||
|
| Mnemonic | Notes |
|
||||||
|
|---|---|
|
||||||
|
| `CALL` | Call subroutine |
|
||||||
|
| `DUFFCOPY` | |
|
||||||
|
| `DUFFZERO` | |
|
||||||
|
| `END` | |
|
||||||
|
| `FUNCDATA` | |
|
||||||
|
| `GETCALLERPC` | |
|
||||||
|
| `JMP` | Unconditional jump |
|
||||||
|
| `NOP` | |
|
||||||
|
| `PCALIGN` | |
|
||||||
|
| `PCALIGNMAX` | |
|
||||||
|
| `PCDATA` | |
|
||||||
|
| `RET` | Return |
|
||||||
|
| `TEXT` | |
|
||||||
|
| `UNDEF` | |
|
||||||
|
| `ADD` | Integer add |
|
||||||
|
| `ADDI` | Add immediate |
|
||||||
|
| `ADDIW` | Add immediate (32-bit) |
|
||||||
|
| `ADDUW` | |
|
||||||
|
| `ADDW` | Add (32-bit) |
|
||||||
|
| `AMOADDD` | Atomic add doubleword |
|
||||||
|
| `AMOADDW` | Atomic add word |
|
||||||
|
| `AMOANDD` | |
|
||||||
|
| `AMOANDW` | |
|
||||||
|
| `AMOMAXD` | |
|
||||||
|
| `AMOMAXUD` | |
|
||||||
|
| `AMOMAXUW` | |
|
||||||
|
| `AMOMAXW` | |
|
||||||
|
| `AMOMIND` | |
|
||||||
|
| `AMOMINUD` | |
|
||||||
|
| `AMOMINUW` | |
|
||||||
|
| `AMOMINW` | |
|
||||||
|
| `AMOORD` | |
|
||||||
|
| `AMOORW` | |
|
||||||
|
| `AMOSWAPD` | Atomic swap doubleword |
|
||||||
|
| `AMOSWAPW` | Atomic swap word |
|
||||||
|
| `AMOXORD` | |
|
||||||
|
| `AMOXORW` | |
|
||||||
|
| `AND` | Bitwise AND |
|
||||||
|
| `ANDI` | AND immediate |
|
||||||
|
| `ANDN` | |
|
||||||
|
| `AUIPC` | Add upper immediate to PC |
|
||||||
|
| `BCLR` | |
|
||||||
|
| `BCLRI` | |
|
||||||
|
| `BEQ` | Branch if equal |
|
||||||
|
| `BEQZ` | |
|
||||||
|
| `BEXT` | |
|
||||||
|
| `BEXTI` | |
|
||||||
|
| `BGE` | Branch if greater or equal |
|
||||||
|
| `BGEU` | Branch if greater or equal unsigned |
|
||||||
|
| `BGEZ` | |
|
||||||
|
| `BGT` | |
|
||||||
|
| `BGTU` | |
|
||||||
|
| `BGTZ` | |
|
||||||
|
| `BINV` | |
|
||||||
|
| `BINVI` | |
|
||||||
|
| `BLE` | |
|
||||||
|
| `BLEU` | |
|
||||||
|
| `BLEZ` | |
|
||||||
|
| `BLT` | Branch if less than |
|
||||||
|
| `BLTU` | Branch if less than unsigned |
|
||||||
|
| `BLTZ` | |
|
||||||
|
| `BNE` | Branch if not equal |
|
||||||
|
| `BNEZ` | |
|
||||||
|
| `BSET` | |
|
||||||
|
| `BSETI` | |
|
||||||
|
| `CADD` | |
|
||||||
|
| `CADDI` | |
|
||||||
|
| `CADDI16SP` | |
|
||||||
|
| `CADDI4SPN` | |
|
||||||
|
| `CADDIW` | |
|
||||||
|
| `CADDW` | |
|
||||||
|
| `CAND` | |
|
||||||
|
| `CANDI` | |
|
||||||
|
| `CBEQZ` | |
|
||||||
|
| `CBNEZ` | |
|
||||||
|
| `CEBREAK` | |
|
||||||
|
| `CFLD` | |
|
||||||
|
| `CFLDSP` | |
|
||||||
|
| `CFSD` | |
|
||||||
|
| `CFSDSP` | |
|
||||||
|
| `CJ` | |
|
||||||
|
| `CJALR` | |
|
||||||
|
| `CJR` | |
|
||||||
|
| `CLD` | |
|
||||||
|
| `CLDSP` | |
|
||||||
|
| `CLI` | |
|
||||||
|
| `CLUI` | |
|
||||||
|
| `CLW` | |
|
||||||
|
| `CLWSP` | |
|
||||||
|
| `CLZ` | |
|
||||||
|
| `CLZW` | |
|
||||||
|
| `CMV` | |
|
||||||
|
| `CNOP` | |
|
||||||
|
| `COR` | |
|
||||||
|
| `CPOP` | |
|
||||||
|
| `CPOPW` | |
|
||||||
|
| `CSD` | |
|
||||||
|
| `CSDSP` | |
|
||||||
|
| `CSLLI` | |
|
||||||
|
| `CSRAI` | |
|
||||||
|
| `CSRLI` | |
|
||||||
|
| `CSRRC` | |
|
||||||
|
| `CSRRCI` | |
|
||||||
|
| `CSRRS` | |
|
||||||
|
| `CSRRSI` | |
|
||||||
|
| `CSRRW` | |
|
||||||
|
| `CSRRWI` | |
|
||||||
|
| `CSUB` | |
|
||||||
|
| `CSUBW` | |
|
||||||
|
| `CSW` | |
|
||||||
|
| `CSWSP` | |
|
||||||
|
| `CTZ` | |
|
||||||
|
| `CTZW` | |
|
||||||
|
| `CXOR` | |
|
||||||
|
| `CZEROEQZ` | |
|
||||||
|
| `CZERONEZ` | |
|
||||||
|
| `DIV` | Divide |
|
||||||
|
| `DIVU` | Divide unsigned |
|
||||||
|
| `DIVUW` | |
|
||||||
|
| `DIVW` | Divide (32-bit) |
|
||||||
|
| `DRET` | |
|
||||||
|
| `EBREAK` | Breakpoint |
|
||||||
|
| `ECALL` | Environment call |
|
||||||
|
| `FABSD` | |
|
||||||
|
| `FABSS` | |
|
||||||
|
| `FADDD` | FP add (double) |
|
||||||
|
| `FADDQ` | |
|
||||||
|
| `FADDS` | FP add (single) |
|
||||||
|
| `FCLASSD` | |
|
||||||
|
| `FCLASSQ` | |
|
||||||
|
| `FCLASSS` | |
|
||||||
|
| `FCVTDL` | |
|
||||||
|
| `FCVTDLU` | |
|
||||||
|
| `FCVTDQ` | |
|
||||||
|
| `FCVTDS` | |
|
||||||
|
| `FCVTDW` | |
|
||||||
|
| `FCVTDWU` | |
|
||||||
|
| `FCVTLD` | |
|
||||||
|
| `FCVTLQ` | |
|
||||||
|
| `FCVTLS` | |
|
||||||
|
| `FCVTLUD` | |
|
||||||
|
| `FCVTLUQ` | |
|
||||||
|
| `FCVTLUS` | |
|
||||||
|
| `FCVTQD` | |
|
||||||
|
| `FCVTQL` | |
|
||||||
|
| `FCVTQLU` | |
|
||||||
|
| `FCVTQS` | |
|
||||||
|
| `FCVTQW` | |
|
||||||
|
| `FCVTQWU` | |
|
||||||
|
| `FCVTSD` | |
|
||||||
|
| `FCVTSL` | |
|
||||||
|
| `FCVTSLU` | |
|
||||||
|
| `FCVTSQ` | |
|
||||||
|
| `FCVTSW` | |
|
||||||
|
| `FCVTSWU` | |
|
||||||
|
| `FCVTWD` | |
|
||||||
|
| `FCVTWQ` | |
|
||||||
|
| `FCVTWS` | |
|
||||||
|
| `FCVTWUD` | |
|
||||||
|
| `FCVTWUQ` | |
|
||||||
|
| `FCVTWUS` | |
|
||||||
|
| `FDIVD` | FP divide (double) |
|
||||||
|
| `FDIVQ` | |
|
||||||
|
| `FDIVS` | FP divide (single) |
|
||||||
|
| `FENCE` | Memory barrier |
|
||||||
|
| `FEQD` | |
|
||||||
|
| `FEQQ` | |
|
||||||
|
| `FEQS` | |
|
||||||
|
| `FLD` | FP load doubleword |
|
||||||
|
| `FLED` | |
|
||||||
|
| `FLEQ` | |
|
||||||
|
| `FLES` | |
|
||||||
|
| `FLQ` | |
|
||||||
|
| `FLTD` | |
|
||||||
|
| `FLTQ` | |
|
||||||
|
| `FLTS` | |
|
||||||
|
| `FLW` | FP load word |
|
||||||
|
| `FMADDD` | |
|
||||||
|
| `FMADDQ` | |
|
||||||
|
| `FMADDS` | |
|
||||||
|
| `FMAXD` | |
|
||||||
|
| `FMAXQ` | |
|
||||||
|
| `FMAXS` | |
|
||||||
|
| `FMIND` | |
|
||||||
|
| `FMINQ` | |
|
||||||
|
| `FMINS` | |
|
||||||
|
| `FMSUBD` | |
|
||||||
|
| `FMSUBQ` | |
|
||||||
|
| `FMSUBS` | |
|
||||||
|
| `FMULD` | FP multiply (double) |
|
||||||
|
| `FMULQ` | |
|
||||||
|
| `FMULS` | FP multiply (single) |
|
||||||
|
| `FMVDX` | |
|
||||||
|
| `FMVSX` | |
|
||||||
|
| `FMVWX` | |
|
||||||
|
| `FMVXD` | |
|
||||||
|
| `FMVXS` | |
|
||||||
|
| `FMVXW` | |
|
||||||
|
| `FNED` | |
|
||||||
|
| `FNEGD` | |
|
||||||
|
| `FNEGS` | |
|
||||||
|
| `FNES` | |
|
||||||
|
| `FNMADDD` | |
|
||||||
|
| `FNMADDQ` | |
|
||||||
|
| `FNMADDS` | |
|
||||||
|
| `FNMSUBD` | |
|
||||||
|
| `FNMSUBQ` | |
|
||||||
|
| `FNMSUBS` | |
|
||||||
|
| `FSD` | FP store doubleword |
|
||||||
|
| `FSGNJD` | |
|
||||||
|
| `FSGNJND` | |
|
||||||
|
| `FSGNJNQ` | |
|
||||||
|
| `FSGNJNS` | |
|
||||||
|
| `FSGNJQ` | |
|
||||||
|
| `FSGNJS` | |
|
||||||
|
| `FSGNJXD` | |
|
||||||
|
| `FSGNJXQ` | |
|
||||||
|
| `FSGNJXS` | |
|
||||||
|
| `FSQ` | |
|
||||||
|
| `FSQRTD` | |
|
||||||
|
| `FSQRTQ` | |
|
||||||
|
| `FSQRTS` | |
|
||||||
|
| `FSUBD` | FP subtract (double) |
|
||||||
|
| `FSUBQ` | |
|
||||||
|
| `FSUBS` | FP subtract (single) |
|
||||||
|
| `FSW` | FP store word |
|
||||||
|
| `JAL` | Jump and link |
|
||||||
|
| `JALR` | Jump and link register |
|
||||||
|
| `LB` | Load byte |
|
||||||
|
| `LBU` | Load byte unsigned |
|
||||||
|
| `LD` | Load doubleword |
|
||||||
|
| `LH` | Load halfword |
|
||||||
|
| `LHU` | Load halfword unsigned |
|
||||||
|
| `LRD` | Load-reserved doubleword |
|
||||||
|
| `LRW` | Load-reserved word |
|
||||||
|
| `LUI` | Load upper immediate |
|
||||||
|
| `LW` | Load word |
|
||||||
|
| `LWU` | Load word unsigned |
|
||||||
|
| `MAX` | |
|
||||||
|
| `MAXU` | |
|
||||||
|
| `MIN` | |
|
||||||
|
| `MINU` | |
|
||||||
|
| `MOV` | |
|
||||||
|
| `MOVB` | |
|
||||||
|
| `MOVBU` | |
|
||||||
|
| `MOVD` | |
|
||||||
|
| `MOVF` | |
|
||||||
|
| `MOVH` | |
|
||||||
|
| `MOVHU` | |
|
||||||
|
| `MOVW` | |
|
||||||
|
| `MOVWU` | |
|
||||||
|
| `MRET` | |
|
||||||
|
| `MUL` | Multiply |
|
||||||
|
| `MULH` | Multiply high |
|
||||||
|
| `MULHSU` | Multiply high signed/unsigned |
|
||||||
|
| `MULHU` | Multiply high unsigned |
|
||||||
|
| `MULW` | Multiply (32-bit) |
|
||||||
|
| `NEG` | |
|
||||||
|
| `NEGW` | |
|
||||||
|
| `NOT` | |
|
||||||
|
| `OR` | Bitwise OR |
|
||||||
|
| `ORCB` | |
|
||||||
|
| `ORI` | OR immediate |
|
||||||
|
| `ORN` | |
|
||||||
|
| `RDCYCLE` | |
|
||||||
|
| `RDINSTRET` | |
|
||||||
|
| `RDTIME` | |
|
||||||
|
| `REM` | Remainder |
|
||||||
|
| `REMU` | Remainder unsigned |
|
||||||
|
| `REMUW` | |
|
||||||
|
| `REMW` | |
|
||||||
|
| `REV8` | |
|
||||||
|
| `ROL` | |
|
||||||
|
| `ROLW` | |
|
||||||
|
| `ROR` | |
|
||||||
|
| `RORI` | |
|
||||||
|
| `RORIW` | |
|
||||||
|
| `RORW` | |
|
||||||
|
| `SB` | Store byte |
|
||||||
|
| `SBREAK` | |
|
||||||
|
| `SCALL` | |
|
||||||
|
| `SCD` | Store-conditional doubleword |
|
||||||
|
| `SCW` | Store-conditional word |
|
||||||
|
| `SD` | Store doubleword |
|
||||||
|
| `SEQZ` | |
|
||||||
|
| `SEXTB` | |
|
||||||
|
| `SEXTH` | |
|
||||||
|
| `SFENCEVMA` | |
|
||||||
|
| `SH` | Store halfword |
|
||||||
|
| `SH1ADD` | |
|
||||||
|
| `SH1ADDUW` | |
|
||||||
|
| `SH2ADD` | |
|
||||||
|
| `SH2ADDUW` | |
|
||||||
|
| `SH3ADD` | |
|
||||||
|
| `SH3ADDUW` | |
|
||||||
|
| `SLL` | Shift left logical |
|
||||||
|
| `SLLI` | Shift left logical immediate |
|
||||||
|
| `SLLIUW` | |
|
||||||
|
| `SLLIW` | |
|
||||||
|
| `SLLW` | |
|
||||||
|
| `SLT` | Set if less than |
|
||||||
|
| `SLTI` | Set if less than immediate |
|
||||||
|
| `SLTIU` | Set if less than unsigned immediate |
|
||||||
|
| `SLTU` | Set if less than unsigned |
|
||||||
|
| `SNEZ` | |
|
||||||
|
| `SRA` | Shift right arithmetic |
|
||||||
|
| `SRAI` | Shift right arithmetic immediate |
|
||||||
|
| `SRAIW` | |
|
||||||
|
| `SRAW` | |
|
||||||
|
| `SRET` | |
|
||||||
|
| `SRL` | Shift right logical |
|
||||||
|
| `SRLI` | Shift right logical immediate |
|
||||||
|
| `SRLIW` | |
|
||||||
|
| `SRLW` | |
|
||||||
|
| `SUB` | Integer subtract |
|
||||||
|
| `SUBW` | Subtract (32-bit) |
|
||||||
|
| `SW` | Store word |
|
||||||
|
| `VAADDUVV` | |
|
||||||
|
| `VAADDUVX` | |
|
||||||
|
| `VAADDVV` | |
|
||||||
|
| `VAADDVX` | |
|
||||||
|
| `VADCVIM` | |
|
||||||
|
| `VADCVVM` | |
|
||||||
|
| `VADCVXM` | |
|
||||||
|
| `VADDVI` | |
|
||||||
|
| `VADDVV` | |
|
||||||
|
| `VADDVX` | |
|
||||||
|
| `VANDVI` | |
|
||||||
|
| `VANDVV` | |
|
||||||
|
| `VANDVX` | |
|
||||||
|
| `VASUBUVV` | |
|
||||||
|
| `VASUBUVX` | |
|
||||||
|
| `VASUBVV` | |
|
||||||
|
| `VASUBVX` | |
|
||||||
|
| `VCOMPRESSVM` | |
|
||||||
|
| `VCPOPM` | |
|
||||||
|
| `VDIVUVV` | |
|
||||||
|
| `VDIVUVX` | |
|
||||||
|
| `VDIVVV` | |
|
||||||
|
| `VDIVVX` | |
|
||||||
|
| `VFABSV` | |
|
||||||
|
| `VFADDVF` | |
|
||||||
|
| `VFADDVV` | |
|
||||||
|
| `VFCLASSV` | |
|
||||||
|
| `VFCVTFXUV` | |
|
||||||
|
| `VFCVTFXV` | |
|
||||||
|
| `VFCVTRTZXFV` | |
|
||||||
|
| `VFCVTRTZXUFV` | |
|
||||||
|
| `VFCVTXFV` | |
|
||||||
|
| `VFCVTXUFV` | |
|
||||||
|
| `VFDIVVF` | |
|
||||||
|
| `VFDIVVV` | |
|
||||||
|
| `VFIRSTM` | |
|
||||||
|
| `VFMACCVF` | |
|
||||||
|
| `VFMACCVV` | |
|
||||||
|
| `VFMADDVF` | |
|
||||||
|
| `VFMADDVV` | |
|
||||||
|
| `VFMAXVF` | |
|
||||||
|
| `VFMAXVV` | |
|
||||||
|
| `VFMERGEVFM` | |
|
||||||
|
| `VFMINVF` | |
|
||||||
|
| `VFMINVV` | |
|
||||||
|
| `VFMSACVF` | |
|
||||||
|
| `VFMSACVV` | |
|
||||||
|
| `VFMSUBVF` | |
|
||||||
|
| `VFMSUBVV` | |
|
||||||
|
| `VFMULVF` | |
|
||||||
|
| `VFMULVV` | |
|
||||||
|
| `VFMVFS` | |
|
||||||
|
| `VFMVSF` | |
|
||||||
|
| `VFMVVF` | |
|
||||||
|
| `VFNCVTFFW` | |
|
||||||
|
| `VFNCVTFXUW` | |
|
||||||
|
| `VFNCVTFXW` | |
|
||||||
|
| `VFNCVTRODFFW` | |
|
||||||
|
| `VFNCVTRTZXFW` | |
|
||||||
|
| `VFNCVTRTZXUFW` | |
|
||||||
|
| `VFNCVTXFW` | |
|
||||||
|
| `VFNCVTXUFW` | |
|
||||||
|
| `VFNEGV` | |
|
||||||
|
| `VFNMACCVF` | |
|
||||||
|
| `VFNMACCVV` | |
|
||||||
|
| `VFNMADDVF` | |
|
||||||
|
| `VFNMADDVV` | |
|
||||||
|
| `VFNMSACVF` | |
|
||||||
|
| `VFNMSACVV` | |
|
||||||
|
| `VFNMSUBVF` | |
|
||||||
|
| `VFNMSUBVV` | |
|
||||||
|
| `VFRDIVVF` | |
|
||||||
|
| `VFREC7V` | |
|
||||||
|
| `VFREDMAXVS` | |
|
||||||
|
| `VFREDMINVS` | |
|
||||||
|
| `VFREDOSUMVS` | |
|
||||||
|
| `VFREDUSUMVS` | |
|
||||||
|
| `VFRSQRT7V` | |
|
||||||
|
| `VFRSUBVF` | |
|
||||||
|
| `VFSGNJNVF` | |
|
||||||
|
| `VFSGNJNVV` | |
|
||||||
|
| `VFSGNJVF` | |
|
||||||
|
| `VFSGNJVV` | |
|
||||||
|
| `VFSGNJXVF` | |
|
||||||
|
| `VFSGNJXVV` | |
|
||||||
|
| `VFSLIDE1DOWNVF` | |
|
||||||
|
| `VFSLIDE1UPVF` | |
|
||||||
|
| `VFSQRTV` | |
|
||||||
|
| `VFSUBVF` | |
|
||||||
|
| `VFSUBVV` | |
|
||||||
|
| `VFWADDVF` | |
|
||||||
|
| `VFWADDVV` | |
|
||||||
|
| `VFWADDWF` | |
|
||||||
|
| `VFWADDWV` | |
|
||||||
|
| `VFWCVTFFV` | |
|
||||||
|
| `VFWCVTFXUV` | |
|
||||||
|
| `VFWCVTFXV` | |
|
||||||
|
| `VFWCVTRTZXFV` | |
|
||||||
|
| `VFWCVTRTZXUFV` | |
|
||||||
|
| `VFWCVTXFV` | |
|
||||||
|
| `VFWCVTXUFV` | |
|
||||||
|
| `VFWMACCVF` | |
|
||||||
|
| `VFWMACCVV` | |
|
||||||
|
| `VFWMSACVF` | |
|
||||||
|
| `VFWMSACVV` | |
|
||||||
|
| `VFWMULVF` | |
|
||||||
|
| `VFWMULVV` | |
|
||||||
|
| `VFWNMACCVF` | |
|
||||||
|
| `VFWNMACCVV` | |
|
||||||
|
| `VFWNMSACVF` | |
|
||||||
|
| `VFWNMSACVV` | |
|
||||||
|
| `VFWREDOSUMVS` | |
|
||||||
|
| `VFWREDUSUMVS` | |
|
||||||
|
| `VFWSUBVF` | |
|
||||||
|
| `VFWSUBVV` | |
|
||||||
|
| `VFWSUBWF` | |
|
||||||
|
| `VFWSUBWV` | |
|
||||||
|
| `VIDV` | |
|
||||||
|
| `VIOTAM` | |
|
||||||
|
| `VL1RE16V` | |
|
||||||
|
| `VL1RE32V` | |
|
||||||
|
| `VL1RE64V` | |
|
||||||
|
| `VL1RE8V` | |
|
||||||
|
| `VL1RV` | |
|
||||||
|
| `VL2RE16V` | |
|
||||||
|
| `VL2RE32V` | |
|
||||||
|
| `VL2RE64V` | |
|
||||||
|
| `VL2RE8V` | |
|
||||||
|
| `VL2RV` | |
|
||||||
|
| `VL4RE16V` | |
|
||||||
|
| `VL4RE32V` | |
|
||||||
|
| `VL4RE64V` | |
|
||||||
|
| `VL4RE8V` | |
|
||||||
|
| `VL4RV` | |
|
||||||
|
| `VL8RE16V` | |
|
||||||
|
| `VL8RE32V` | |
|
||||||
|
| `VL8RE64V` | |
|
||||||
|
| `VL8RE8V` | |
|
||||||
|
| `VL8RV` | |
|
||||||
|
| `VLE16FFV` | |
|
||||||
|
| `VLE16V` | |
|
||||||
|
| `VLE32FFV` | |
|
||||||
|
| `VLE32V` | |
|
||||||
|
| `VLE64FFV` | |
|
||||||
|
| `VLE64V` | |
|
||||||
|
| `VLE8FFV` | |
|
||||||
|
| `VLE8V` | |
|
||||||
|
| `VLMV` | |
|
||||||
|
| `VLOXEI16V` | |
|
||||||
|
| `VLOXEI32V` | |
|
||||||
|
| `VLOXEI64V` | |
|
||||||
|
| `VLOXEI8V` | |
|
||||||
|
| `VLOXSEG2EI16V` | |
|
||||||
|
| `VLOXSEG2EI32V` | |
|
||||||
|
| `VLOXSEG2EI64V` | |
|
||||||
|
| `VLOXSEG2EI8V` | |
|
||||||
|
| `VLOXSEG3EI16V` | |
|
||||||
|
| `VLOXSEG3EI32V` | |
|
||||||
|
| `VLOXSEG3EI64V` | |
|
||||||
|
| `VLOXSEG3EI8V` | |
|
||||||
|
| `VLOXSEG4EI16V` | |
|
||||||
|
| `VLOXSEG4EI32V` | |
|
||||||
|
| `VLOXSEG4EI64V` | |
|
||||||
|
| `VLOXSEG4EI8V` | |
|
||||||
|
| `VLOXSEG5EI16V` | |
|
||||||
|
| `VLOXSEG5EI32V` | |
|
||||||
|
| `VLOXSEG5EI64V` | |
|
||||||
|
| `VLOXSEG5EI8V` | |
|
||||||
|
| `VLOXSEG6EI16V` | |
|
||||||
|
| `VLOXSEG6EI32V` | |
|
||||||
|
| `VLOXSEG6EI64V` | |
|
||||||
|
| `VLOXSEG6EI8V` | |
|
||||||
|
| `VLOXSEG7EI16V` | |
|
||||||
|
| `VLOXSEG7EI32V` | |
|
||||||
|
| `VLOXSEG7EI64V` | |
|
||||||
|
| `VLOXSEG7EI8V` | |
|
||||||
|
| `VLOXSEG8EI16V` | |
|
||||||
|
| `VLOXSEG8EI32V` | |
|
||||||
|
| `VLOXSEG8EI64V` | |
|
||||||
|
| `VLOXSEG8EI8V` | |
|
||||||
|
| `VLSE16V` | |
|
||||||
|
| `VLSE32V` | |
|
||||||
|
| `VLSE64V` | |
|
||||||
|
| `VLSE8V` | |
|
||||||
|
| `VLSEG2E16FFV` | |
|
||||||
|
| `VLSEG2E16V` | |
|
||||||
|
| `VLSEG2E32FFV` | |
|
||||||
|
| `VLSEG2E32V` | |
|
||||||
|
| `VLSEG2E64FFV` | |
|
||||||
|
| `VLSEG2E64V` | |
|
||||||
|
| `VLSEG2E8FFV` | |
|
||||||
|
| `VLSEG2E8V` | |
|
||||||
|
| `VLSEG3E16FFV` | |
|
||||||
|
| `VLSEG3E16V` | |
|
||||||
|
| `VLSEG3E32FFV` | |
|
||||||
|
| `VLSEG3E32V` | |
|
||||||
|
| `VLSEG3E64FFV` | |
|
||||||
|
| `VLSEG3E64V` | |
|
||||||
|
| `VLSEG3E8FFV` | |
|
||||||
|
| `VLSEG3E8V` | |
|
||||||
|
| `VLSEG4E16FFV` | |
|
||||||
|
| `VLSEG4E16V` | |
|
||||||
|
| `VLSEG4E32FFV` | |
|
||||||
|
| `VLSEG4E32V` | |
|
||||||
|
| `VLSEG4E64FFV` | |
|
||||||
|
| `VLSEG4E64V` | |
|
||||||
|
| `VLSEG4E8FFV` | |
|
||||||
|
| `VLSEG4E8V` | |
|
||||||
|
| `VLSEG5E16FFV` | |
|
||||||
|
| `VLSEG5E16V` | |
|
||||||
|
| `VLSEG5E32FFV` | |
|
||||||
|
| `VLSEG5E32V` | |
|
||||||
|
| `VLSEG5E64FFV` | |
|
||||||
|
| `VLSEG5E64V` | |
|
||||||
|
| `VLSEG5E8FFV` | |
|
||||||
|
| `VLSEG5E8V` | |
|
||||||
|
| `VLSEG6E16FFV` | |
|
||||||
|
| `VLSEG6E16V` | |
|
||||||
|
| `VLSEG6E32FFV` | |
|
||||||
|
| `VLSEG6E32V` | |
|
||||||
|
| `VLSEG6E64FFV` | |
|
||||||
|
| `VLSEG6E64V` | |
|
||||||
|
| `VLSEG6E8FFV` | |
|
||||||
|
| `VLSEG6E8V` | |
|
||||||
|
| `VLSEG7E16FFV` | |
|
||||||
|
| `VLSEG7E16V` | |
|
||||||
|
| `VLSEG7E32FFV` | |
|
||||||
|
| `VLSEG7E32V` | |
|
||||||
|
| `VLSEG7E64FFV` | |
|
||||||
|
| `VLSEG7E64V` | |
|
||||||
|
| `VLSEG7E8FFV` | |
|
||||||
|
| `VLSEG7E8V` | |
|
||||||
|
| `VLSEG8E16FFV` | |
|
||||||
|
| `VLSEG8E16V` | |
|
||||||
|
| `VLSEG8E32FFV` | |
|
||||||
|
| `VLSEG8E32V` | |
|
||||||
|
| `VLSEG8E64FFV` | |
|
||||||
|
| `VLSEG8E64V` | |
|
||||||
|
| `VLSEG8E8FFV` | |
|
||||||
|
| `VLSEG8E8V` | |
|
||||||
|
| `VLSSEG2E16V` | |
|
||||||
|
| `VLSSEG2E32V` | |
|
||||||
|
| `VLSSEG2E64V` | |
|
||||||
|
| `VLSSEG2E8V` | |
|
||||||
|
| `VLSSEG3E16V` | |
|
||||||
|
| `VLSSEG3E32V` | |
|
||||||
|
| `VLSSEG3E64V` | |
|
||||||
|
| `VLSSEG3E8V` | |
|
||||||
|
| `VLSSEG4E16V` | |
|
||||||
|
| `VLSSEG4E32V` | |
|
||||||
|
| `VLSSEG4E64V` | |
|
||||||
|
| `VLSSEG4E8V` | |
|
||||||
|
| `VLSSEG5E16V` | |
|
||||||
|
| `VLSSEG5E32V` | |
|
||||||
|
| `VLSSEG5E64V` | |
|
||||||
|
| `VLSSEG5E8V` | |
|
||||||
|
| `VLSSEG6E16V` | |
|
||||||
|
| `VLSSEG6E32V` | |
|
||||||
|
| `VLSSEG6E64V` | |
|
||||||
|
| `VLSSEG6E8V` | |
|
||||||
|
| `VLSSEG7E16V` | |
|
||||||
|
| `VLSSEG7E32V` | |
|
||||||
|
| `VLSSEG7E64V` | |
|
||||||
|
| `VLSSEG7E8V` | |
|
||||||
|
| `VLSSEG8E16V` | |
|
||||||
|
| `VLSSEG8E32V` | |
|
||||||
|
| `VLSSEG8E64V` | |
|
||||||
|
| `VLSSEG8E8V` | |
|
||||||
|
| `VLUXEI16V` | |
|
||||||
|
| `VLUXEI32V` | |
|
||||||
|
| `VLUXEI64V` | |
|
||||||
|
| `VLUXEI8V` | |
|
||||||
|
| `VLUXSEG2EI16V` | |
|
||||||
|
| `VLUXSEG2EI32V` | |
|
||||||
|
| `VLUXSEG2EI64V` | |
|
||||||
|
| `VLUXSEG2EI8V` | |
|
||||||
|
| `VLUXSEG3EI16V` | |
|
||||||
|
| `VLUXSEG3EI32V` | |
|
||||||
|
| `VLUXSEG3EI64V` | |
|
||||||
|
| `VLUXSEG3EI8V` | |
|
||||||
|
| `VLUXSEG4EI16V` | |
|
||||||
|
| `VLUXSEG4EI32V` | |
|
||||||
|
| `VLUXSEG4EI64V` | |
|
||||||
|
| `VLUXSEG4EI8V` | |
|
||||||
|
| `VLUXSEG5EI16V` | |
|
||||||
|
| `VLUXSEG5EI32V` | |
|
||||||
|
| `VLUXSEG5EI64V` | |
|
||||||
|
| `VLUXSEG5EI8V` | |
|
||||||
|
| `VLUXSEG6EI16V` | |
|
||||||
|
| `VLUXSEG6EI32V` | |
|
||||||
|
| `VLUXSEG6EI64V` | |
|
||||||
|
| `VLUXSEG6EI8V` | |
|
||||||
|
| `VLUXSEG7EI16V` | |
|
||||||
|
| `VLUXSEG7EI32V` | |
|
||||||
|
| `VLUXSEG7EI64V` | |
|
||||||
|
| `VLUXSEG7EI8V` | |
|
||||||
|
| `VLUXSEG8EI16V` | |
|
||||||
|
| `VLUXSEG8EI32V` | |
|
||||||
|
| `VLUXSEG8EI64V` | |
|
||||||
|
| `VLUXSEG8EI8V` | |
|
||||||
|
| `VMACCVV` | |
|
||||||
|
| `VMACCVX` | |
|
||||||
|
| `VMADCVI` | |
|
||||||
|
| `VMADCVIM` | |
|
||||||
|
| `VMADCVV` | |
|
||||||
|
| `VMADCVVM` | |
|
||||||
|
| `VMADCVX` | |
|
||||||
|
| `VMADCVXM` | |
|
||||||
|
| `VMADDVV` | |
|
||||||
|
| `VMADDVX` | |
|
||||||
|
| `VMANDMM` | |
|
||||||
|
| `VMANDNMM` | |
|
||||||
|
| `VMAXUVV` | |
|
||||||
|
| `VMAXUVX` | |
|
||||||
|
| `VMAXVV` | |
|
||||||
|
| `VMAXVX` | |
|
||||||
|
| `VMCLRM` | |
|
||||||
|
| `VMERGEVIM` | |
|
||||||
|
| `VMERGEVVM` | |
|
||||||
|
| `VMERGEVXM` | |
|
||||||
|
| `VMFEQVF` | |
|
||||||
|
| `VMFEQVV` | |
|
||||||
|
| `VMFGEVF` | |
|
||||||
|
| `VMFGEVV` | |
|
||||||
|
| `VMFGTVF` | |
|
||||||
|
| `VMFGTVV` | |
|
||||||
|
| `VMFLEVF` | |
|
||||||
|
| `VMFLEVV` | |
|
||||||
|
| `VMFLTVF` | |
|
||||||
|
| `VMFLTVV` | |
|
||||||
|
| `VMFNEVF` | |
|
||||||
|
| `VMFNEVV` | |
|
||||||
|
| `VMINUVV` | |
|
||||||
|
| `VMINUVX` | |
|
||||||
|
| `VMINVV` | |
|
||||||
|
| `VMINVX` | |
|
||||||
|
| `VMMVM` | |
|
||||||
|
| `VMNANDMM` | |
|
||||||
|
| `VMNORMM` | |
|
||||||
|
| `VMNOTM` | |
|
||||||
|
| `VMORMM` | |
|
||||||
|
| `VMORNMM` | |
|
||||||
|
| `VMSBCVV` | |
|
||||||
|
| `VMSBCVVM` | |
|
||||||
|
| `VMSBCVX` | |
|
||||||
|
| `VMSBCVXM` | |
|
||||||
|
| `VMSBFM` | |
|
||||||
|
| `VMSEQVI` | |
|
||||||
|
| `VMSEQVV` | |
|
||||||
|
| `VMSEQVX` | |
|
||||||
|
| `VMSETM` | |
|
||||||
|
| `VMSGEUVI` | |
|
||||||
|
| `VMSGEUVV` | |
|
||||||
|
| `VMSGEVI` | |
|
||||||
|
| `VMSGEVV` | |
|
||||||
|
| `VMSGTUVI` | |
|
||||||
|
| `VMSGTUVV` | |
|
||||||
|
| `VMSGTUVX` | |
|
||||||
|
| `VMSGTVI` | |
|
||||||
|
| `VMSGTVV` | |
|
||||||
|
| `VMSGTVX` | |
|
||||||
|
| `VMSIFM` | |
|
||||||
|
| `VMSLEUVI` | |
|
||||||
|
| `VMSLEUVV` | |
|
||||||
|
| `VMSLEUVX` | |
|
||||||
|
| `VMSLEVI` | |
|
||||||
|
| `VMSLEVV` | |
|
||||||
|
| `VMSLEVX` | |
|
||||||
|
| `VMSLTUVI` | |
|
||||||
|
| `VMSLTUVV` | |
|
||||||
|
| `VMSLTUVX` | |
|
||||||
|
| `VMSLTVI` | |
|
||||||
|
| `VMSLTVV` | |
|
||||||
|
| `VMSLTVX` | |
|
||||||
|
| `VMSNEVI` | |
|
||||||
|
| `VMSNEVV` | |
|
||||||
|
| `VMSNEVX` | |
|
||||||
|
| `VMSOFM` | |
|
||||||
|
| `VMULHSUVV` | |
|
||||||
|
| `VMULHSUVX` | |
|
||||||
|
| `VMULHUVV` | |
|
||||||
|
| `VMULHUVX` | |
|
||||||
|
| `VMULHVV` | |
|
||||||
|
| `VMULHVX` | |
|
||||||
|
| `VMULVV` | |
|
||||||
|
| `VMULVX` | |
|
||||||
|
| `VMV1RV` | |
|
||||||
|
| `VMV2RV` | |
|
||||||
|
| `VMV4RV` | |
|
||||||
|
| `VMV8RV` | |
|
||||||
|
| `VMVSX` | |
|
||||||
|
| `VMVVI` | |
|
||||||
|
| `VMVVV` | |
|
||||||
|
| `VMVVX` | |
|
||||||
|
| `VMVXS` | |
|
||||||
|
| `VMXNORMM` | |
|
||||||
|
| `VMXORMM` | |
|
||||||
|
| `VNCLIPUWI` | |
|
||||||
|
| `VNCLIPUWV` | |
|
||||||
|
| `VNCLIPUWX` | |
|
||||||
|
| `VNCLIPWI` | |
|
||||||
|
| `VNCLIPWV` | |
|
||||||
|
| `VNCLIPWX` | |
|
||||||
|
| `VNCVTXXW` | |
|
||||||
|
| `VNEGV` | |
|
||||||
|
| `VNMSACVV` | |
|
||||||
|
| `VNMSACVX` | |
|
||||||
|
| `VNMSUBVV` | |
|
||||||
|
| `VNMSUBVX` | |
|
||||||
|
| `VNOTV` | |
|
||||||
|
| `VNSRAWI` | |
|
||||||
|
| `VNSRAWV` | |
|
||||||
|
| `VNSRAWX` | |
|
||||||
|
| `VNSRLWI` | |
|
||||||
|
| `VNSRLWV` | |
|
||||||
|
| `VNSRLWX` | |
|
||||||
|
| `VORVI` | |
|
||||||
|
| `VORVV` | |
|
||||||
|
| `VORVX` | |
|
||||||
|
| `VREDANDVS` | |
|
||||||
|
| `VREDMAXUVS` | |
|
||||||
|
| `VREDMAXVS` | |
|
||||||
|
| `VREDMINUVS` | |
|
||||||
|
| `VREDMINVS` | |
|
||||||
|
| `VREDORVS` | |
|
||||||
|
| `VREDSUMVS` | |
|
||||||
|
| `VREDXORVS` | |
|
||||||
|
| `VREMUVV` | |
|
||||||
|
| `VREMUVX` | |
|
||||||
|
| `VREMVV` | |
|
||||||
|
| `VREMVX` | |
|
||||||
|
| `VRGATHEREI16VV` | |
|
||||||
|
| `VRGATHERVI` | |
|
||||||
|
| `VRGATHERVV` | |
|
||||||
|
| `VRGATHERVX` | |
|
||||||
|
| `VRSUBVI` | |
|
||||||
|
| `VRSUBVX` | |
|
||||||
|
| `VS1RV` | |
|
||||||
|
| `VS2RV` | |
|
||||||
|
| `VS4RV` | |
|
||||||
|
| `VS8RV` | |
|
||||||
|
| `VSADDUVI` | |
|
||||||
|
| `VSADDUVV` | |
|
||||||
|
| `VSADDUVX` | |
|
||||||
|
| `VSADDVI` | |
|
||||||
|
| `VSADDVV` | |
|
||||||
|
| `VSADDVX` | |
|
||||||
|
| `VSBCVVM` | |
|
||||||
|
| `VSBCVXM` | |
|
||||||
|
| `VSE16V` | |
|
||||||
|
| `VSE32V` | |
|
||||||
|
| `VSE64V` | |
|
||||||
|
| `VSE8V` | |
|
||||||
|
| `VSETIVLI` | |
|
||||||
|
| `VSETVL` | |
|
||||||
|
| `VSETVLI` | |
|
||||||
|
| `VSEXTVF2` | |
|
||||||
|
| `VSEXTVF4` | |
|
||||||
|
| `VSEXTVF8` | |
|
||||||
|
| `VSLIDE1DOWNVX` | |
|
||||||
|
| `VSLIDE1UPVX` | |
|
||||||
|
| `VSLIDEDOWNVI` | |
|
||||||
|
| `VSLIDEDOWNVX` | |
|
||||||
|
| `VSLIDEUPVI` | |
|
||||||
|
| `VSLIDEUPVX` | |
|
||||||
|
| `VSLLVI` | |
|
||||||
|
| `VSLLVV` | |
|
||||||
|
| `VSLLVX` | |
|
||||||
|
| `VSMULVV` | |
|
||||||
|
| `VSMULVX` | |
|
||||||
|
| `VSMV` | |
|
||||||
|
| `VSOXEI16V` | |
|
||||||
|
| `VSOXEI32V` | |
|
||||||
|
| `VSOXEI64V` | |
|
||||||
|
| `VSOXEI8V` | |
|
||||||
|
| `VSOXSEG2EI16V` | |
|
||||||
|
| `VSOXSEG2EI32V` | |
|
||||||
|
| `VSOXSEG2EI64V` | |
|
||||||
|
| `VSOXSEG2EI8V` | |
|
||||||
|
| `VSOXSEG3EI16V` | |
|
||||||
|
| `VSOXSEG3EI32V` | |
|
||||||
|
| `VSOXSEG3EI64V` | |
|
||||||
|
| `VSOXSEG3EI8V` | |
|
||||||
|
| `VSOXSEG4EI16V` | |
|
||||||
|
| `VSOXSEG4EI32V` | |
|
||||||
|
| `VSOXSEG4EI64V` | |
|
||||||
|
| `VSOXSEG4EI8V` | |
|
||||||
|
| `VSOXSEG5EI16V` | |
|
||||||
|
| `VSOXSEG5EI32V` | |
|
||||||
|
| `VSOXSEG5EI64V` | |
|
||||||
|
| `VSOXSEG5EI8V` | |
|
||||||
|
| `VSOXSEG6EI16V` | |
|
||||||
|
| `VSOXSEG6EI32V` | |
|
||||||
|
| `VSOXSEG6EI64V` | |
|
||||||
|
| `VSOXSEG6EI8V` | |
|
||||||
|
| `VSOXSEG7EI16V` | |
|
||||||
|
| `VSOXSEG7EI32V` | |
|
||||||
|
| `VSOXSEG7EI64V` | |
|
||||||
|
| `VSOXSEG7EI8V` | |
|
||||||
|
| `VSOXSEG8EI16V` | |
|
||||||
|
| `VSOXSEG8EI32V` | |
|
||||||
|
| `VSOXSEG8EI64V` | |
|
||||||
|
| `VSOXSEG8EI8V` | |
|
||||||
|
| `VSRAVI` | |
|
||||||
|
| `VSRAVV` | |
|
||||||
|
| `VSRAVX` | |
|
||||||
|
| `VSRLVI` | |
|
||||||
|
| `VSRLVV` | |
|
||||||
|
| `VSRLVX` | |
|
||||||
|
| `VSSE16V` | |
|
||||||
|
| `VSSE32V` | |
|
||||||
|
| `VSSE64V` | |
|
||||||
|
| `VSSE8V` | |
|
||||||
|
| `VSSEG2E16V` | |
|
||||||
|
| `VSSEG2E32V` | |
|
||||||
|
| `VSSEG2E64V` | |
|
||||||
|
| `VSSEG2E8V` | |
|
||||||
|
| `VSSEG3E16V` | |
|
||||||
|
| `VSSEG3E32V` | |
|
||||||
|
| `VSSEG3E64V` | |
|
||||||
|
| `VSSEG3E8V` | |
|
||||||
|
| `VSSEG4E16V` | |
|
||||||
|
| `VSSEG4E32V` | |
|
||||||
|
| `VSSEG4E64V` | |
|
||||||
|
| `VSSEG4E8V` | |
|
||||||
|
| `VSSEG5E16V` | |
|
||||||
|
| `VSSEG5E32V` | |
|
||||||
|
| `VSSEG5E64V` | |
|
||||||
|
| `VSSEG5E8V` | |
|
||||||
|
| `VSSEG6E16V` | |
|
||||||
|
| `VSSEG6E32V` | |
|
||||||
|
| `VSSEG6E64V` | |
|
||||||
|
| `VSSEG6E8V` | |
|
||||||
|
| `VSSEG7E16V` | |
|
||||||
|
| `VSSEG7E32V` | |
|
||||||
|
| `VSSEG7E64V` | |
|
||||||
|
| `VSSEG7E8V` | |
|
||||||
|
| `VSSEG8E16V` | |
|
||||||
|
| `VSSEG8E32V` | |
|
||||||
|
| `VSSEG8E64V` | |
|
||||||
|
| `VSSEG8E8V` | |
|
||||||
|
| `VSSRAVI` | |
|
||||||
|
| `VSSRAVV` | |
|
||||||
|
| `VSSRAVX` | |
|
||||||
|
| `VSSRLVI` | |
|
||||||
|
| `VSSRLVV` | |
|
||||||
|
| `VSSRLVX` | |
|
||||||
|
| `VSSSEG2E16V` | |
|
||||||
|
| `VSSSEG2E32V` | |
|
||||||
|
| `VSSSEG2E64V` | |
|
||||||
|
| `VSSSEG2E8V` | |
|
||||||
|
| `VSSSEG3E16V` | |
|
||||||
|
| `VSSSEG3E32V` | |
|
||||||
|
| `VSSSEG3E64V` | |
|
||||||
|
| `VSSSEG3E8V` | |
|
||||||
|
| `VSSSEG4E16V` | |
|
||||||
|
| `VSSSEG4E32V` | |
|
||||||
|
| `VSSSEG4E64V` | |
|
||||||
|
| `VSSSEG4E8V` | |
|
||||||
|
| `VSSSEG5E16V` | |
|
||||||
|
| `VSSSEG5E32V` | |
|
||||||
|
| `VSSSEG5E64V` | |
|
||||||
|
| `VSSSEG5E8V` | |
|
||||||
|
| `VSSSEG6E16V` | |
|
||||||
|
| `VSSSEG6E32V` | |
|
||||||
|
| `VSSSEG6E64V` | |
|
||||||
|
| `VSSSEG6E8V` | |
|
||||||
|
| `VSSSEG7E16V` | |
|
||||||
|
| `VSSSEG7E32V` | |
|
||||||
|
| `VSSSEG7E64V` | |
|
||||||
|
| `VSSSEG7E8V` | |
|
||||||
|
| `VSSSEG8E16V` | |
|
||||||
|
| `VSSSEG8E32V` | |
|
||||||
|
| `VSSSEG8E64V` | |
|
||||||
|
| `VSSSEG8E8V` | |
|
||||||
|
| `VSSUBUVV` | |
|
||||||
|
| `VSSUBUVX` | |
|
||||||
|
| `VSSUBVV` | |
|
||||||
|
| `VSSUBVX` | |
|
||||||
|
| `VSUBVV` | |
|
||||||
|
| `VSUBVX` | |
|
||||||
|
| `VSUXEI16V` | |
|
||||||
|
| `VSUXEI32V` | |
|
||||||
|
| `VSUXEI64V` | |
|
||||||
|
| `VSUXEI8V` | |
|
||||||
|
| `VSUXSEG2EI16V` | |
|
||||||
|
| `VSUXSEG2EI32V` | |
|
||||||
|
| `VSUXSEG2EI64V` | |
|
||||||
|
| `VSUXSEG2EI8V` | |
|
||||||
|
| `VSUXSEG3EI16V` | |
|
||||||
|
| `VSUXSEG3EI32V` | |
|
||||||
|
| `VSUXSEG3EI64V` | |
|
||||||
|
| `VSUXSEG3EI8V` | |
|
||||||
|
| `VSUXSEG4EI16V` | |
|
||||||
|
| `VSUXSEG4EI32V` | |
|
||||||
|
| `VSUXSEG4EI64V` | |
|
||||||
|
| `VSUXSEG4EI8V` | |
|
||||||
|
| `VSUXSEG5EI16V` | |
|
||||||
|
| `VSUXSEG5EI32V` | |
|
||||||
|
| `VSUXSEG5EI64V` | |
|
||||||
|
| `VSUXSEG5EI8V` | |
|
||||||
|
| `VSUXSEG6EI16V` | |
|
||||||
|
| `VSUXSEG6EI32V` | |
|
||||||
|
| `VSUXSEG6EI64V` | |
|
||||||
|
| `VSUXSEG6EI8V` | |
|
||||||
|
| `VSUXSEG7EI16V` | |
|
||||||
|
| `VSUXSEG7EI32V` | |
|
||||||
|
| `VSUXSEG7EI64V` | |
|
||||||
|
| `VSUXSEG7EI8V` | |
|
||||||
|
| `VSUXSEG8EI16V` | |
|
||||||
|
| `VSUXSEG8EI32V` | |
|
||||||
|
| `VSUXSEG8EI64V` | |
|
||||||
|
| `VSUXSEG8EI8V` | |
|
||||||
|
| `VWADDUVV` | |
|
||||||
|
| `VWADDUVX` | |
|
||||||
|
| `VWADDUWV` | |
|
||||||
|
| `VWADDUWX` | |
|
||||||
|
| `VWADDVV` | |
|
||||||
|
| `VWADDVX` | |
|
||||||
|
| `VWADDWV` | |
|
||||||
|
| `VWADDWX` | |
|
||||||
|
| `VWCVTUXXV` | |
|
||||||
|
| `VWCVTXXV` | |
|
||||||
|
| `VWMACCSUVV` | |
|
||||||
|
| `VWMACCSUVX` | |
|
||||||
|
| `VWMACCUSVX` | |
|
||||||
|
| `VWMACCUVV` | |
|
||||||
|
| `VWMACCUVX` | |
|
||||||
|
| `VWMACCVV` | |
|
||||||
|
| `VWMACCVX` | |
|
||||||
|
| `VWMULSUVV` | |
|
||||||
|
| `VWMULSUVX` | |
|
||||||
|
| `VWMULUVV` | |
|
||||||
|
| `VWMULUVX` | |
|
||||||
|
| `VWMULVV` | |
|
||||||
|
| `VWMULVX` | |
|
||||||
|
| `VWREDSUMUVS` | |
|
||||||
|
| `VWREDSUMVS` | |
|
||||||
|
| `VWSUBUVV` | |
|
||||||
|
| `VWSUBUVX` | |
|
||||||
|
| `VWSUBUWV` | |
|
||||||
|
| `VWSUBUWX` | |
|
||||||
|
| `VWSUBVV` | |
|
||||||
|
| `VWSUBVX` | |
|
||||||
|
| `VWSUBWV` | |
|
||||||
|
| `VWSUBWX` | |
|
||||||
|
| `VXORVI` | |
|
||||||
|
| `VXORVV` | |
|
||||||
|
| `VXORVX` | |
|
||||||
|
| `VZEXTVF2` | |
|
||||||
|
| `VZEXTVF4` | |
|
||||||
|
| `VZEXTVF8` | |
|
||||||
|
| `WFI` | |
|
||||||
|
| `WORD` | |
|
||||||
|
| `XNOR` | |
|
||||||
|
| `XOR` | Bitwise XOR |
|
||||||
|
| `XORI` | XOR immediate |
|
||||||
|
| `ZEXTH` | |
|
||||||
|
|
||||||
|
Recognised: 975 mnemonics.
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
# Language: lexicon, statements and expressions
|
||||||
|
|
||||||
|
Layer 1, the common language, the same on every target. Verified against
|
||||||
|
`go tool asm` of Go 1.27.1 and against gasm's parser, which is differentially
|
||||||
|
tested against the toolchain. The authoritative sources behind this page are
|
||||||
|
the assembler's lexer (`cmd/asm/internal/lex`), its parser
|
||||||
|
(`cmd/asm/internal/asm/parse.go`) and the toolchain's own test data.
|
||||||
|
|
||||||
|
## Source files and targets
|
||||||
|
|
||||||
|
An assembly source is a `.s` file. The Go build convention names a
|
||||||
|
target-specific file with the architecture suffix, `_amd64.s`, `_arm64.s`,
|
||||||
|
`_riscv64.s` or `_loong64.s`; files without a suffix are portable across
|
||||||
|
targets. The same assembler program assembles every target: `go tool asm`
|
||||||
|
picks the target from the `GOOS` and `GOARCH` environment variables, and gasm
|
||||||
|
from the file name suffix or the `--arch` flag.
|
||||||
|
|
||||||
|
## Character set and identifiers
|
||||||
|
|
||||||
|
Sources are ASCII text. An identifier is a sequence of ASCII letters, digits
|
||||||
|
and underscores, digits never first, with exactly two additions:
|
||||||
|
|
||||||
|
- U+00B7, the middle dot `·`, stands for the period in a symbol's
|
||||||
|
package-qualified name;
|
||||||
|
- U+2215, the division slash `∕`, stands for the slash in a package path.
|
||||||
|
|
||||||
|
The two substitutions exist because the parser treats a real period and a
|
||||||
|
real slash as punctuation. The syntax is otherwise uppercase throughout:
|
||||||
|
instructions, registers and directives are written in upper case. The one
|
||||||
|
inherited exception is the `g` register name on 32-bit ARM.
|
||||||
|
|
||||||
|
## Comments
|
||||||
|
|
||||||
|
Two comment forms, both Go's:
|
||||||
|
|
||||||
|
```text
|
||||||
|
// a line comment
|
||||||
|
/* a block comment */
|
||||||
|
```
|
||||||
|
|
||||||
|
A comment of the form `//go:build` or the legacy `+build` comment is not a
|
||||||
|
plain comment: the lexer reports it to the build system as a build
|
||||||
|
constraint.
|
||||||
|
|
||||||
|
## Statements
|
||||||
|
|
||||||
|
The grammar of one line, from the parser:
|
||||||
|
|
||||||
|
```text
|
||||||
|
{label:} WORD[.qualifier] [ arg {, arg} ] (';' | '\n')
|
||||||
|
```
|
||||||
|
|
||||||
|
- A **label** is an identifier followed by a colon. Labels are
|
||||||
|
function-local: two functions in one file may reuse the same name, and a
|
||||||
|
reference resolves within the function that contains it. A branch
|
||||||
|
instruction names its target with a bare label operand, and the assembler
|
||||||
|
resolves it PC-relative. The explicit forms `offset(PC)`, a constant
|
||||||
|
counting instructions from the branch, and `name(SB)`, a cross-function
|
||||||
|
static reference, appear as branch targets as well.
|
||||||
|
- **WORD** is the instruction or directive name, upper case. On the ARM
|
||||||
|
family the word may carry a dot qualifier selecting a condition or shift
|
||||||
|
mode, such as the condition suffixes on 32-bit ARM; the amd64, arm64,
|
||||||
|
riscv64 and loong64 assemblies carry no instruction qualifiers apart from
|
||||||
|
their own width suffixes, which are part of the mnemonic.
|
||||||
|
- **Arguments** are separated by commas, with no trailing comma.
|
||||||
|
- A statement ends at a newline or at a semicolon, so several statements fit
|
||||||
|
on one line separated by `;`. Blank lines are free.
|
||||||
|
|
||||||
|
The first word of a line is a directive if it is one of the directive names
|
||||||
|
(TEXT, DATA, GLOBL, FUNCDATA, PCDATA, PCALIGN) and an instruction otherwise.
|
||||||
|
Unknown instruction names are errors; the instruction set is the set the
|
||||||
|
toolchain itself defines per target, plus the common pseudo-instructions.
|
||||||
|
|
||||||
|
## Literals
|
||||||
|
|
||||||
|
| Form | Examples | Notes |
|
||||||
|
|---|---|---|
|
||||||
|
| Integer | `0`, `42`, `0x2a`, `0o52`, `0b101010`, `1_000` | decimal, hexadecimal, octal and binary forms with Go's digit separators |
|
||||||
|
| Character | `'a'`, `'\n'`, `'\x41'` | single quoted, Go escape rules |
|
||||||
|
| String | `"this program can only run\n"` | double quoted, Go escape rules; accepted where an operand takes raw bytes, in practice a DATA initialiser |
|
||||||
|
| Float | `1.5`, `1e9` | accepted by the lexer; only meaningful where the target's encoding takes a float operand |
|
||||||
|
|
||||||
|
## Expressions
|
||||||
|
|
||||||
|
Constant expressions may appear wherever a constant is expected: in
|
||||||
|
immediates after `$`, in memory offsets, in frame and data sizes. The
|
||||||
|
evaluator works on unsigned 64-bit values with Go's operator precedence, and
|
||||||
|
the parser states its grammar in exactly those terms:
|
||||||
|
|
||||||
|
```text
|
||||||
|
expr = term { '+' term | '-' term | '|' term | '^' term }
|
||||||
|
term = factor { '*' factor | '/' factor | '%' factor | '<<' factor | '>>' factor | '&' factor }
|
||||||
|
factor = const | '+' factor | '-' factor | '~' factor | '(' expr ')'
|
||||||
|
```
|
||||||
|
|
||||||
|
Two consequences are worth naming, because the arithmetic surprises people
|
||||||
|
who read it as C:
|
||||||
|
|
||||||
|
- Shifts bind at the multiplicative level, next to `*` and `&`, while `|`
|
||||||
|
and `^` bind at the additive level. `$x<<1|3` computes `(x<<1)|3`, which
|
||||||
|
differs from `x*2+3` whenever `x` is odd. Plan 9 arithmetic is Go
|
||||||
|
precedence applied to a byte-oriented language, not the C expression it
|
||||||
|
resembles.
|
||||||
|
- The evaluator is unsigned and guarded: division or modulo by zero is an
|
||||||
|
error, and so is dividing a value with the high bit set; shift counts must
|
||||||
|
be non-negative; and a right shift of a value with the high bit set is
|
||||||
|
rejected rather than sign-extended.
|
||||||
|
|
||||||
|
An address expression such as `(index*4)(base)` is evaluated at assembly
|
||||||
|
time only if every name in it is a constant; a name that resolves to a
|
||||||
|
symbol turns the expression into a relocation request, never into a folded
|
||||||
|
constant.
|
||||||
|
|
||||||
|
Named constants enter expressions through the preprocessor (`#define`,
|
||||||
|
`-D`) and, in Go-embedded packages, through the generated `go_asm.h`; see
|
||||||
|
PREPROCESSOR.md and RUNTIME.md.
|
||||||
|
|
||||||
|
## The common pseudo-instructions
|
||||||
|
|
||||||
|
A handful of instructions exist on every target, assembled by the assembler
|
||||||
|
itself rather than the encoder: `NOP`, which emits the target's no-operation
|
||||||
|
encoding, and the frame-management pseudo-instructions the compiler emits
|
||||||
|
(`FUNCDATA`, `PCDATA`) which DIRECTIVES.md specifies. Everything else is the
|
||||||
|
target's own instruction set, and the assembler knows only the instructions
|
||||||
|
the toolchain's compiler emits; a hand-written kernel wanting more lays the
|
||||||
|
encoding down with `BYTE` on amd64 or waits for the extended layer.
|
||||||
|
|
||||||
|
## Case study: three lines, decomposed
|
||||||
|
|
||||||
|
```text
|
||||||
|
B.EQ 1(PC) // arm64: condition qualifier on the mnemonic,
|
||||||
|
// target one instruction past the branch
|
||||||
|
JMP done // every target: bare label, function-local,
|
||||||
|
// resolved PC-relative
|
||||||
|
MOVQ $reader__size>>3, CX // amd64: expression over a go_asm.h constant
|
||||||
|
```
|
||||||
|
|
||||||
|
The first shows a qualifier and the explicit relative target form; the second
|
||||||
|
the ordinary label reference; the third an expression over a generated
|
||||||
|
constant. Labels are reusable between functions without conflict.
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
# LoongArch 64
|
||||||
|
|
||||||
|
Layer 1, target page. Verified against `go tool asm` of Go 1.27.1, against
|
||||||
|
the toolchain's own loong64 assembler manual (`cmd/internal/obj/loong64/doc.go`)
|
||||||
|
and against gasm's encoder, whose output is compared byte for byte with the
|
||||||
|
toolchain's. The complete mnemonic inventory lives in the generated appendix
|
||||||
|
[INSTRUCTIONS-LOONG64.md](INSTRUCTIONS-LOONG64.md).
|
||||||
|
|
||||||
|
## Registers
|
||||||
|
|
||||||
|
- General purpose `R0` to `R31`, floating point `F0` to `F31`, LSX vectors
|
||||||
|
`V0` to `V31` and LASX vectors `X0` to `X31`.
|
||||||
|
- Fixed roles from the toolchain's table: `R0` is the constant zero, `R1`
|
||||||
|
the return address, `R3` the stack pointer, `R22` the goroutine pointer,
|
||||||
|
`R29` the closure context and `R30` the assembler's temporary. `R12`,
|
||||||
|
`R13`, `R14`, `R15` and `R20` serve the PLT and trampoline sequences:
|
||||||
|
usable in assembly, but saved before any call.
|
||||||
|
|
||||||
|
## Widths ride the mnemonic
|
||||||
|
|
||||||
|
| Suffix | Width |
|
||||||
|
|---|---|
|
||||||
|
| `B`, `BU` | 8-bit, 8-bit unsigned |
|
||||||
|
| `H`, `HU` | 16-bit, 16-bit unsigned |
|
||||||
|
| `W`, `WU` | 32-bit, 32-bit unsigned |
|
||||||
|
| `V` | 64-bit |
|
||||||
|
| `F`, `D` | 32-bit and 64-bit float |
|
||||||
|
| `V` prefix (LSX) | 128-bit vector |
|
||||||
|
| `XV` prefix (LASX) | 256-bit vector |
|
||||||
|
|
||||||
|
The MOV series is the load and store interface: `MOVB (R2), R3` loads a
|
||||||
|
byte, `MOVV (R2), R3` a double word, `VMOVQ (R2), V1` a 128-bit vector and
|
||||||
|
`XVMOVQ (R2), X1` a 256-bit one.
|
||||||
|
|
||||||
|
## Operand order
|
||||||
|
|
||||||
|
Most instructions appear in left-to-right assignment order: `ADDV R11, R12,
|
||||||
|
R13` is `add.d R13, R12, R11`, and the two-operand form
|
||||||
|
`OR R5, R6` assigns into R6. Exceptions:
|
||||||
|
|
||||||
|
- Jump and branch instructions keep the GNU order: `BEQ R0, R4, label1`.
|
||||||
|
- The bitfield family is `BSTRINSW`, `BSTRINSV`, `BSTRPICKW`, `BSTRPICKV`
|
||||||
|
`$<msb>, <Rj>, $<lsb>, <Rd>`.
|
||||||
|
|
||||||
|
## Addressing
|
||||||
|
|
||||||
|
- Plain: `offset(Rbase)`.
|
||||||
|
- Base plus offset **register**, no scale: `(R4)(R5)`, as in
|
||||||
|
`MOVB (R4)(R5), R6`, the `ldx` family.
|
||||||
|
- The pointer loads and stores `MOVWP` and `MOVVP` take a source-level
|
||||||
|
16-bit offset that the encoder halves into the 14-bit field, writing
|
||||||
|
`MOVWP 8(R4), R5` as `ldptr.w r5, r4, $2`.
|
||||||
|
|
||||||
|
## Vector element syntax
|
||||||
|
|
||||||
|
The `VMOVQ` and `XVMOVQ` transfer family covers register-to-vector moves
|
||||||
|
with arrangement and index suffixes: `VMOVQ Rj, Vd.B[index]` inserts a
|
||||||
|
general register into one lane, `VMOVQ Vj.B[index], Rd` extracts one,
|
||||||
|
`VMOVQ Rj, Vd.B16` broadcasts across all sixteen, and `VMOVQ Vj.B[index],
|
||||||
|
Vd.B16` replicates one lane. The broadcast-from-memory form takes the true
|
||||||
|
byte offset at source level, which the encoder rescales per arrangement.
|
||||||
|
The permute and extract families take their 8-bit control word first:
|
||||||
|
`VPERMIW ui8, Vj, Vd`, `VEXTRINSB ui8, Vj, Vd`.
|
||||||
|
|
||||||
|
## Alignment
|
||||||
|
|
||||||
|
`PCALIGN $n` pads with NOOP to a power-of-two boundary between 8 and 2048,
|
||||||
|
and this target additionally auto-aligns loop heads to 16 bytes.
|
||||||
|
|
||||||
|
## Atomics, barriers and prefetch
|
||||||
|
|
||||||
|
- The `AM` atomic family comes in plain and `_DB` flavours; the `_DB`
|
||||||
|
forms, such as `AMSWAPDBW`, complete the atomic sequence and act as a
|
||||||
|
full data barrier. Within the AM family the destination and base
|
||||||
|
registers may not coincide and the destination may not equal the operand
|
||||||
|
register: one is an exception, the other silently unspecified.
|
||||||
|
- `DBAR` carries the graded hint encoding documented for LA664 and later,
|
||||||
|
with hint 0x700 as the read-after-read lightweight barrier; older cores
|
||||||
|
treat every hint as the full barrier.
|
||||||
|
- `PRELD offset(Rbase), $hint` prefetches with the documented hints (0
|
||||||
|
load to L1, 2 load to L3, 8 store to L1); `PRELDX` adds the encoded
|
||||||
|
block descriptor.
|
||||||
|
- `ALSL`-family shift-and-add writes the desired shift amount in source and
|
||||||
|
encodes one less: `ALSLV $4, R4, R5, R6` shifts by 4.
|
||||||
|
- `ADDV16 si16<<16, Rj, Rd` is the high-immediate add paired with the
|
||||||
|
pointer loads for GOT relative access.
|
||||||
|
|
||||||
|
## Relocations
|
||||||
|
|
||||||
|
`R_CALLLOONG64` for the 28-bit BL, `R_LOONG64_CALL36` for the
|
||||||
|
PCADDU18I-plus-JIRL pair, the `R_LOONG64_ADDR`, `ADDR64`, `TLS_LE`, `TLS_IE`,
|
||||||
|
`GOT` and `GOT64` high and low pairs, the aligned conditional jump forms
|
||||||
|
`R_JMP16LOONG64` and `R_JMP21LOONG64`, and `R_LOONG64_ADD64` and `SUB64`
|
||||||
|
for in-place arithmetic, all specified in [GOOBJ.md](../GOOBJ.md).
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
# Operands: grammar, pseudo-registers, addressing and symbols
|
||||||
|
|
||||||
|
Layer 1, the common language. Verified against `go tool asm` of Go 1.27.1 and
|
||||||
|
against gasm's parser. The operand grammar is the part of the language that
|
||||||
|
varies most between targets, so this page fixes the common grammar and the
|
||||||
|
pseudo-registers; the per architecture pages carry the register names and the
|
||||||
|
addressing quirks each target adds.
|
||||||
|
|
||||||
|
## The four operand kinds
|
||||||
|
|
||||||
|
Every operand is one of four kinds:
|
||||||
|
|
||||||
|
```text
|
||||||
|
R1 register
|
||||||
|
$4 immediate
|
||||||
|
label branch target or symbol
|
||||||
|
-8(BX)(DI*4) memory
|
||||||
|
```
|
||||||
|
|
||||||
|
**Operands go source first, destination last**: `MOVQ x+0(FP), AX` loads the
|
||||||
|
argument into AX. This is the opposite of Intel order and the same order as
|
||||||
|
AT&T, with the sigils removed: registers are bare names, immediates take
|
||||||
|
`$`, memory is `offset(base)`.
|
||||||
|
|
||||||
|
## Registers
|
||||||
|
|
||||||
|
A register operand is its bare name, with no prefix: `AX`, `X15`, `R14` on
|
||||||
|
amd64; `R0` to `R30`, `ZR`, `V0` to `V31` on arm64; `X0` to `X31`, `F0` to
|
||||||
|
`F31`, `V0` on riscv64; `R0` to `R31`, `F0` to `F31`, `V0` on loong64.
|
||||||
|
Sub-register and width selection rides the mnemonic, not the operand: the
|
||||||
|
amd64 family spells `MOVB`, `MOVW`, `MOVL`, `MOVQ`, and the arm64 family
|
||||||
|
suffices `B`, `H`, `S`, `D`, `Q` on the shared forms. Each architecture page
|
||||||
|
lists its registers and the reserved ones.
|
||||||
|
|
||||||
|
## Immediates
|
||||||
|
|
||||||
|
`$` introduces a constant: `$42`, `$-1`, `$0x2a`, `$'A'`, `$bufSize`. The
|
||||||
|
`$` applies to the whole constant expression that follows, so
|
||||||
|
`$(4*8+reader__size)` is one immediate. Without the `$`, a number in operand
|
||||||
|
position is an address, not a value; the classic error `ADDQ 1, AX` asks the
|
||||||
|
assembler for the byte at address 1.
|
||||||
|
|
||||||
|
The one place a `$` number is not an immediate is the frame and argument
|
||||||
|
size field of TEXT, `$16-24`, which is two separate constants and not a
|
||||||
|
subtraction; DIRECTIVES.md specifies it.
|
||||||
|
|
||||||
|
## Memory
|
||||||
|
|
||||||
|
```text
|
||||||
|
offset(base)
|
||||||
|
offset(base)(index*scale)
|
||||||
|
```
|
||||||
|
|
||||||
|
Both parts are optional where the target allows them: `(BX)` is the memory
|
||||||
|
at BX, `foo+16(SB)` is a global, and on amd64 `foo+32(SP)(R9*8)` adds a
|
||||||
|
scaled index. `offset` is a constant expression, optionally carrying a
|
||||||
|
symbol name. The extensions beyond `offset(base)` are where the targets
|
||||||
|
diverge, and each belongs to its architecture page: amd64 carries the
|
||||||
|
`index*scale` form with scale 1, 2, 4 or 8 and its own rules on which
|
||||||
|
registers may index; loong64 writes base plus index as `(R4)(R5)`; the ARM
|
||||||
|
family attaches shift amounts to the index register in its own spelling.
|
||||||
|
|
||||||
|
The address arithmetic is on **byte addresses**: the offset is added to the
|
||||||
|
base as it stands, whatever the operand width of the instruction. Loading
|
||||||
|
the third 8-byte word of an array at BX is `16(BX)`, not `2(BX)`.
|
||||||
|
|
||||||
|
## The four pseudo-registers
|
||||||
|
|
||||||
|
Four names denote locations no target register holds, and they mean the same
|
||||||
|
on every architecture:
|
||||||
|
|
||||||
|
- **FP**, the frame pointer: the arguments and results of the current
|
||||||
|
function, at positive offsets, in the order the Go prototype declares
|
||||||
|
them. Every FP reference must carry a name: `x+0(FP)`, and an unnamed
|
||||||
|
`0(FP)` is rejected. Results follow arguments; an unnamed result is called
|
||||||
|
`ret`.
|
||||||
|
- **SP**, the virtual stack pointer: the high end of the function's local
|
||||||
|
frame, so locals live at negative offsets, `x-8(SP)`. A reference without
|
||||||
|
a name and without a plus, `-8(SP)`, addresses the **hardware** stack
|
||||||
|
pointer instead: the two spellings are one character apart and mean
|
||||||
|
different registers. That is the sharpest edge in the language and the
|
||||||
|
source of the deepest bugs.
|
||||||
|
- **SB**, the static base: the origin of memory, used for globals and
|
||||||
|
cross-package symbols, always with a name: `foo(SB)`, `foo+4(SB)`.
|
||||||
|
- **PC**, the program counter: branch targets, and the explicit relative
|
||||||
|
form `1(PC)`.
|
||||||
|
|
||||||
|
## Symbol names
|
||||||
|
|
||||||
|
A symbol's full name is the package path, a period, and the base name. In
|
||||||
|
source, the period is written U+00B7 (`·`) and a slash in the path U+2215
|
||||||
|
(`∕`), because the parser treats the ASCII forms as punctuation. Inside the
|
||||||
|
package's own file, `·Name` is enough and is the preferred spelling, since
|
||||||
|
it survives a rename of the import path.
|
||||||
|
|
||||||
|
| Spelling | Meaning |
|
||||||
|
|---|---|
|
||||||
|
| `·Name(SB)` | this package's Name |
|
||||||
|
| `runtime·morestack(SB)` | another package's morestack |
|
||||||
|
| `sourcedock.dev∕petrbalvin∕pkg·Name(SB)` | fully qualified |
|
||||||
|
| `msg<>(SB)` | file-local, the static of this language; `<>` also makes the ABI field static in the object |
|
||||||
|
| `Name<ABIInternal>(SB)` | ABI-qualified reference, the ABI in angle brackets after the name |
|
||||||
|
|
||||||
|
The object file these symbols produce, with the index rules that decide what
|
||||||
|
is referenced by name and what by index, is specified in
|
||||||
|
[GOOBJ.md](../GOOBJ.md).
|
||||||
|
|
||||||
|
## What vet adds in Go
|
||||||
|
|
||||||
|
Inside a Go package, `go vet`'s asmdecl analyzer checks every FP offset and
|
||||||
|
name against the Go prototype, and checks the declared argument area against
|
||||||
|
the frame. That layer, the prototype requirement and `go_asm.h`, belongs to
|
||||||
|
RUNTIME.md; the grammar above is the whole of what the assembler itself
|
||||||
|
requires.
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
# Preprocessing: include, define and selection
|
||||||
|
|
||||||
|
Layer 1, the common language. Verified against the preprocessor inside
|
||||||
|
`go tool asm` of Go 1.27.1 (`cmd/asm/internal/lex`), whose directives are
|
||||||
|
`#define`, `#undef`, `#include`, `#ifdef`, `#ifndef`, `#else`, `#endif` and
|
||||||
|
`#line`, and against gasm's implementation, which is differentially tested
|
||||||
|
against the toolchain's.
|
||||||
|
|
||||||
|
Input runs through a simplified C preprocessor before the parser sees it.
|
||||||
|
The set is deliberately small: there is no `#if` with constant expressions
|
||||||
|
and no token pasting with `##`. `#line` is honoured, so it changes the
|
||||||
|
positions the assembler reports and records.
|
||||||
|
|
||||||
|
## #include
|
||||||
|
|
||||||
|
```text
|
||||||
|
#include "textflag.h"
|
||||||
|
#include "go_asm.h"
|
||||||
|
#include "defs_linux_amd64.h"
|
||||||
|
```
|
||||||
|
|
||||||
|
The search path, in order: the directory of the including file, then the
|
||||||
|
directories given by repeatable `-I` flags. The assembler seeds no default
|
||||||
|
of its own: a bare `go tool asm` invocation finds none of the standard
|
||||||
|
headers, and it is the `go` build system that passes `$GOROOT/pkg/include`
|
||||||
|
among the `-I` directories when it drives the build. That directory ships
|
||||||
|
`textflag.h`, `funcdata.h` and the per architecture register headers.
|
||||||
|
Includes nest; a file included twice through different paths is processed
|
||||||
|
twice, which is why headers guard their defines.
|
||||||
|
|
||||||
|
## #define and #undef
|
||||||
|
|
||||||
|
```text
|
||||||
|
#define bufSize 1024
|
||||||
|
#define MOVD(d, s) MOVQ s, d
|
||||||
|
#undef bufSize
|
||||||
|
```
|
||||||
|
|
||||||
|
- An object macro replaces its name with its token sequence at the point of
|
||||||
|
use.
|
||||||
|
- A parameterised macro takes its arguments in parentheses and substitutes
|
||||||
|
them into the body. Macro parameters compose with the rest of the
|
||||||
|
language: an argument used with an element suffix, as in `A.S4` on the
|
||||||
|
vector forms, substitutes correctly.
|
||||||
|
- Redefinition is an error; `#undef` first, or pick a new name.
|
||||||
|
- The `-D name[=value]` flag predefines an object macro from the command
|
||||||
|
line, repeatable, exactly as `#define` would; a `-D` without a value
|
||||||
|
defines the name as `1`.
|
||||||
|
- Expansion happens when the name is used, so a macro may expand to
|
||||||
|
instructions, operands or fragments of either, and a macro body may use
|
||||||
|
macros defined before it.
|
||||||
|
|
||||||
|
`textflag.h` and `funcdata.h` are themselves ordinary `#define` files: the
|
||||||
|
flag names and the runtime macros are preprocessor definitions, not language
|
||||||
|
keywords. That is why a missing include produces a parser error at the first
|
||||||
|
use of `NOSPLIT` rather than a complaint about the name.
|
||||||
|
|
||||||
|
## #ifdef, #ifndef, #else, #endif
|
||||||
|
|
||||||
|
```text
|
||||||
|
#ifdef GOOS_windows
|
||||||
|
#define SYSCALL_INT 0x2b
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
|
||||||
|
Selection is by defined-name only: `#ifdef`, `#ifndef`, `#else`, `#endif`,
|
||||||
|
nesting freely. There is no `#if defined(x) && y`, because the preprocessor
|
||||||
|
evaluates no expressions; reach that with a build-tag Go file generating a
|
||||||
|
header, which is exactly how the runtime's own `go_asm.h` and defs headers
|
||||||
|
are produced.
|
||||||
|
|
||||||
|
## What preprocessing does not cover
|
||||||
|
|
||||||
|
The preprocessor is textual and runs first, so it knows nothing of assembly
|
||||||
|
semantics: it does not check that a macro expansion is a legal instruction,
|
||||||
|
and it does not participate in the constant expression evaluator, which runs
|
||||||
|
later, in the parser. A constant folded with `#define` and a constant folded
|
||||||
|
in an operand expression end at the same value through different doors;
|
||||||
|
GOOBJ.md records both in the object identically.
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
# The Plan 9 assembly language
|
||||||
|
|
||||||
|
This directory is the reference for the Plan 9 assembly language as the Go
|
||||||
|
toolchain and gasm accept it, written to be complete enough to implement
|
||||||
|
against. It exists because no such reference exists upstream: Go documents
|
||||||
|
the language on a single page, and the rest of the knowledge lives in the
|
||||||
|
toolchain's source and in the practice of reading it.
|
||||||
|
|
||||||
|
Every page carries the same conformance statement: which layer of the system
|
||||||
|
it describes, which toolchain release it was verified against, and how the
|
||||||
|
claims were checked. Pages in this directory are verified against Go 1.27.1
|
||||||
|
and against gasm's own differential test suite, which compares gasm's
|
||||||
|
behaviour with `go tool asm` byte for byte and output for output.
|
||||||
|
|
||||||
|
## The three layers
|
||||||
|
|
||||||
|
The reference deliberately separates three layers, because their rules have
|
||||||
|
different owners and different lifetimes:
|
||||||
|
|
||||||
|
1. **The common language** (LANGUAGE, OPERANDS, DIRECTIVES,
|
||||||
|
PREPROCESSOR): the syntax, operands, directives and preprocessing, the
|
||||||
|
same on every target and meaningful without a Go runtime.
|
||||||
|
2. **The Go-embedded layer** (RUNTIME): everything that exists only because
|
||||||
|
the code runs inside a Go program: the ABI0 contract, generated wrappers,
|
||||||
|
`go_asm.h`, the garbage collector annotations and `go vet` checks.
|
||||||
|
3. **The standalone layer** (STANDALONE, planned with the standalone
|
||||||
|
compilation phase): using the language outside Go, through gasm's ELF
|
||||||
|
output and the extended instruction set, where the toolchain offers no
|
||||||
|
ground truth and execution testing is the only verification.
|
||||||
|
|
||||||
|
A rule stated in layer 1 holds on every target. A rule stated in layer 2
|
||||||
|
says which part of the Go machinery imposes it. Nothing in layer 3 changes
|
||||||
|
layers 1 or 2; it extends them.
|
||||||
|
|
||||||
|
## Pages
|
||||||
|
|
||||||
|
| Page | Layer | Contents |
|
||||||
|
|---|---|---|
|
||||||
|
| [LANGUAGE.md](LANGUAGE.md) | 1 | lexicon, statement structure, labels, literals, expressions |
|
||||||
|
| [OPERANDS.md](OPERANDS.md) | 1 | operand grammar, pseudo-registers, addressing modes, symbol naming |
|
||||||
|
| [DIRECTIVES.md](DIRECTIVES.md) | 1 | TEXT, DATA, GLOBL, FUNCDATA, PCDATA, PCALIGN and the function flags |
|
||||||
|
| [PREPROCESSOR.md](PREPROCESSOR.md) | 1 | `#include`, `#define`, `#ifdef` and friends, `-D`, `-I` |
|
||||||
|
| [RUNTIME.md](RUNTIME.md) | 2 | ABI0, prototypes, `go_asm.h`, `funcdata.h`, `go vet` |
|
||||||
|
| [AMD64.md](AMD64.md) | 1 | registers, addressing, the frame and split check, families, relocations |
|
||||||
|
| [ARM64.md](ARM64.md) | 1 | registers, the MOV load and store series, special operand orders, SIMD |
|
||||||
|
| [RISCV64.md](RISCV64.md) | 1 | registers and their constrained names, per class operand order, profiles, vector extension |
|
||||||
|
| [LOONG64.md](LOONG64.md) | 1 | registers, width suffixes, vector element syntax, atomics and barriers |
|
||||||
|
| INSTRUCTIONS-AMD64.md and the other three | 1 | generated per architecture inventory of every accepted mnemonic |
|
||||||
|
| STANDALONE.md | 3 | the language outside Go |
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
The common-language core, the Go-embedded layer, all four per-architecture
|
||||||
|
pages and the generated instruction appendices are written and verified.
|
||||||
|
STANDALONE.md lands with the standalone compilation phase. The object format
|
||||||
|
these pages feed is specified in [GOOBJ.md](../GOOBJ.md).
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
# RISC-V 64
|
||||||
|
|
||||||
|
Layer 1, target page. Verified against `go tool asm` of Go 1.27.1, against
|
||||||
|
the toolchain's own riscv64 assembler manual (`cmd/internal/obj/riscv/doc.go`)
|
||||||
|
and against gasm's encoder, whose output is compared byte for byte with the
|
||||||
|
toolchain's. The complete mnemonic inventory lives in the generated appendix
|
||||||
|
[INSTRUCTIONS-RISCV64.md](INSTRUCTIONS-RISCV64.md).
|
||||||
|
|
||||||
|
## Registers
|
||||||
|
|
||||||
|
- Integer: `X0` to `X31`. `X0` is hardwired zero. Three names the toolchain
|
||||||
|
constrains: `X4` must be written through its ABI name `TP`; `X27`, the
|
||||||
|
goroutine pointer, must be written `g` and may not be written `S11`; in
|
||||||
|
shared builds `X3` is off limits and must be written `GP`.
|
||||||
|
- The other integer registers may be written `Xn` or by their ABI names
|
||||||
|
(`A0`, `T0`, `S1`, and so on).
|
||||||
|
- Floating point: `F0` to `F31`. Vector: `V0` to `V31`.
|
||||||
|
- `X26` is the closure pointer and `X31` is the assembler's own scratch
|
||||||
|
register: its value may be clobbered by instruction sequences the
|
||||||
|
assembler inserts, so hand-written code must not rely on it.
|
||||||
|
- There is no reserved frame pointer register on this target.
|
||||||
|
|
||||||
|
## Operand order
|
||||||
|
|
||||||
|
The ordering differs from the ISA manual, and per instruction class:
|
||||||
|
|
||||||
|
- **R-type** is reversed: `ADD X10, X11, X12` is `add x12, x11, x10`.
|
||||||
|
- **I-type arithmetic** keeps that shape with the immediate first:
|
||||||
|
`ADDI $1, X11, X12`.
|
||||||
|
- **Loads and stores** are source first, like every Plan 9 dialect:
|
||||||
|
`MOV 16(X2), X10` loads and `MOV X10, (X2)` stores. The MOV series hides
|
||||||
|
the width; `MOVB` through `MOVD` spell it out.
|
||||||
|
- **Branches** keep the ISA order: `BLT X12, X23, loop1`, which jumps when
|
||||||
|
X12 < X23, the reverse of the SLT operand order.
|
||||||
|
- **FMA** is rotated one place left so the destination comes last:
|
||||||
|
`FMADDS F1, F2, F3, F4`.
|
||||||
|
- **AMO** is likewise rotated: `AMOSWAPW X5, (X6), X7`.
|
||||||
|
- **Ternary abbreviation** is supported and encouraged: `ADD X10, X12` means
|
||||||
|
`ADD X10, X12, X12`.
|
||||||
|
|
||||||
|
Where an R-type instruction has an I-type sibling, the assembler picks the
|
||||||
|
immediate form from the operand: `AND $3, X12, X13` assembles as `ANDI`.
|
||||||
|
|
||||||
|
## Names, suffixes and rounding
|
||||||
|
|
||||||
|
Dots are removed and suffixes are upper-cased: the ISA's `fmv.w.x` is
|
||||||
|
`FMVWX`. Floating-point rounding modes become suffixes, `FCVTLUS.RNE F0,
|
||||||
|
X5`, with RTZ assumed when the suffix is omitted; the toolchain never sets
|
||||||
|
the FCSR.
|
||||||
|
|
||||||
|
## Constants
|
||||||
|
|
||||||
|
- `MOV` materialises any 64-bit integer constant, synthesising it from a
|
||||||
|
few arithmetic instructions where possible and otherwise loading it from
|
||||||
|
a literal pool in the binary.
|
||||||
|
- A 32-bit constant is accepted by `ADDI`, `ANDI`, `ORI` and `XORI`, and
|
||||||
|
the assembler synthesises values that exceed the 12-bit encoding window.
|
||||||
|
- `MOVF` and `MOVD` materialise floating-point constants, encoding them as
|
||||||
|
`FLW` and `FLD` from a pool location unless the constant is exactly 0.0.
|
||||||
|
|
||||||
|
## Extensions and profiles
|
||||||
|
|
||||||
|
The default target profile is rva20u64, selected or raised with the
|
||||||
|
GORISCV64 environment variable. A short list of instructions outside the
|
||||||
|
default profile is synthesised by the assembler when the profile does not
|
||||||
|
provide them, so they are safe without guards: `ANDN`, `MAX`, `MAXU`, `MIN`,
|
||||||
|
`MINU`, `MOVB`, `MOVH`, `MOVHU`, `MOVWU`, `ORN`, `ROL`, `ROLW`, `ROR`,
|
||||||
|
`RORI`, `RORIW`, `RORW`, `XNOR`. The header `asm_riscv64.h` defines the
|
||||||
|
`hasZba`, `hasZbb`, `hasZbs` and `hasV` macros for guarding everything else.
|
||||||
|
|
||||||
|
## Fences and atomics
|
||||||
|
|
||||||
|
`FENCE` takes predecessor and successor sets in that order, uppercase
|
||||||
|
letters, `FENCE R, RW`; a bare `FENCE` is a full fence, as is
|
||||||
|
`FENCE IORW, IORW`. `FENCE.TSO` exists. The ordering bits of `LR`, `SC`
|
||||||
|
and the AMO instructions are not specifiable in source: the assembler sets
|
||||||
|
acquire and release on the AMO instructions, acquire on `LR` and release on
|
||||||
|
`SC`, always.
|
||||||
|
|
||||||
|
## Compressed instructions
|
||||||
|
|
||||||
|
The assembler converts 32-bit instructions to their compressed encodings
|
||||||
|
automatically; the conversion is a property of the emitted machine code, not
|
||||||
|
of the source, and register choice influences how much compresses.
|
||||||
|
Hand-writing compressed instructions in source is accepted but discouraged.
|
||||||
|
The debug flag `compressinstructions=0` turns the automatic conversion off.
|
||||||
|
|
||||||
|
## Vector extension
|
||||||
|
|
||||||
|
`VSETVLI` writes its vtype components in uppercase with the destination
|
||||||
|
last: `VSETVLI X10, E8, M1, TU, MU, X12`. Vector loads and stores are
|
||||||
|
source first like the scalar ones, with an optional stride or index register
|
||||||
|
second and the mask register, when present, always penultimate:
|
||||||
|
`VLE8V (X10), V3`, `VLE8V (X10), V0, V3` for the masked form. Vector
|
||||||
|
arithmetic reverses its operands, `VADDVV V1, V2, V3`, with the mask again
|
||||||
|
penultimate.
|
||||||
|
|
||||||
|
## Relocations
|
||||||
|
|
||||||
|
`R_RISCV_JAL`, `R_RISCV_CALL`, the `R_RISCV_PCREL_ITYPE` and `STYPE` pairs,
|
||||||
|
`R_RISCV_BRANCH`, the compressed branch and jump forms, the TLS and GOT
|
||||||
|
families and `R_RISCV_ADD32` and `SUB32`, all specified in
|
||||||
|
[GOOBJ.md](../GOOBJ.md). The assembler always emits the four-byte
|
||||||
|
`R_DWTXTADDR_U4` flavour inside its DWARF records.
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
# The Go-embedded layer: ABI0, prototypes and the runtime contract
|
||||||
|
|
||||||
|
Layer 2: everything that exists only because the assembly runs inside a Go
|
||||||
|
program. Without a Go runtime this page does not apply; the language of
|
||||||
|
OPERANDS.md and DIRECTIVES.md still does. Verified against Go 1.27.1, against
|
||||||
|
the shipped `funcdata.h` header, and against the object files the toolchain
|
||||||
|
produces, which were parsed and checked field by field while writing
|
||||||
|
[GOOBJ.md](../GOOBJ.md).
|
||||||
|
|
||||||
|
## Hand-written assembly is ABI0
|
||||||
|
|
||||||
|
Go functions compiled from source use ABIInternal, the register-based
|
||||||
|
calling convention, which the toolchain documents as unstable and free to
|
||||||
|
change between releases. A `.s` function is written against ABI0, the stack
|
||||||
|
based convention: arguments and results live in the caller's frame at
|
||||||
|
positive FP offsets, byte-addressed, in declaration order, with no registers
|
||||||
|
assigned at all. The toolchain generates the wrapper that translates between
|
||||||
|
the two; a caller in Go calling an assembly function goes through it, and it
|
||||||
|
is marked `ABIWRAPPER` in the object. Hand-writing a bridge is never needed
|
||||||
|
and never correct.
|
||||||
|
|
||||||
|
## Every assembly function carries a Go prototype
|
||||||
|
|
||||||
|
```go
|
||||||
|
package add
|
||||||
|
|
||||||
|
func Add(x, y int64) int64
|
||||||
|
```
|
||||||
|
|
||||||
|
The body-less declaration is not optional, and not only for the linker: it
|
||||||
|
is what tells the garbage collector which arguments and results hold
|
||||||
|
pointers, and what `go vet` checks the assembly against. Even a function
|
||||||
|
nothing in Go calls gets one. Consequences:
|
||||||
|
|
||||||
|
- The FP operand names and offsets are checked by vet's asmdecl analyzer
|
||||||
|
against the prototype: `x+0(FP)` must name an argument that exists, at the
|
||||||
|
offset the prototype says. A file that assembles and links can still fail
|
||||||
|
vet.
|
||||||
|
- The declared argument area in `$framesize-argsize` is checked against the
|
||||||
|
prototype's size. An omitted argsize marks the argument size unknown
|
||||||
|
(0x80000000 in the object, the value of `ArgsSizeUnknown` from
|
||||||
|
`funcdata.h`), which is the normal spelling for functions with no Go
|
||||||
|
callers.
|
||||||
|
- `//go:noescape` on the declaration tells the compiler that a pointer
|
||||||
|
argument does not escape, for assembly that keeps the pointer beyond the
|
||||||
|
call.
|
||||||
|
|
||||||
|
## The frame, the stack and the collector
|
||||||
|
|
||||||
|
The runtime owns the stack and the pointer map, and assembly must hold up
|
||||||
|
its end of four rules:
|
||||||
|
|
||||||
|
1. **Arguments are initialised on entry; results are not.** A function whose
|
||||||
|
results hold live pointers across a call must zero them and then execute
|
||||||
|
`GO_RESULTS_INITIALIZED`. Designing functions that return no pointers
|
||||||
|
avoids the problem.
|
||||||
|
2. **A frame with calls and no local pointers says so** with
|
||||||
|
`NO_LOCAL_POINTERS`. A frame with local pointers that the runtime cannot
|
||||||
|
see is not allowed at all: assembly cannot describe a pointer-containing
|
||||||
|
local, so it must not have one. Data symbols containing pointers are the
|
||||||
|
same: define them in Go.
|
||||||
|
3. **The stack may move.** Stack growth copies the frame, so no pointer into
|
||||||
|
the frame may be held across a call, and the raw hardware SP register may
|
||||||
|
not be cached across a call either.
|
||||||
|
4. **The split check is not optional by default.** Without NOSPLIT, the
|
||||||
|
assembler inserts the stack-growth preamble, including the morestack
|
||||||
|
block for framed functions; NOSPLIT is a contract that the frame and
|
||||||
|
everything below it fit in the remaining stack segment. On amd64 the
|
||||||
|
assembler also marks small leaf functions NoSplit itself and skips the
|
||||||
|
preamble, so silence is not a promise.
|
||||||
|
|
||||||
|
The simplest safe shape is a leaf function with no local frame and no calls:
|
||||||
|
it needs no annotation beyond the prototype.
|
||||||
|
|
||||||
|
## go_asm.h: Go constants and layout in assembly
|
||||||
|
|
||||||
|
A package with `.s` files gets a generated header. Include it and use the
|
||||||
|
generated names instead of hard-coding layouts, which lie silently when the
|
||||||
|
Go side changes:
|
||||||
|
|
||||||
|
| Go declaration | Assembly name |
|
||||||
|
|---|---|
|
||||||
|
| `const bufSize = 1024` | `const_bufSize` |
|
||||||
|
| field `r` of `type reader struct` | `reader_r` |
|
||||||
|
| size of `type reader struct` | `reader__size` |
|
||||||
|
|
||||||
|
The constants arrive as macros, usable as immediates and offsets, computed
|
||||||
|
from the Go declarations. An ambiguous name, such as a struct that really
|
||||||
|
has a `_size` field, fails the generation with a redefinition error.
|
||||||
|
|
||||||
|
## funcdata.h: the runtime macros
|
||||||
|
|
||||||
|
`$GOROOT/pkg/include/funcdata.h` defines the PCDATA and FUNCDATA ids and the
|
||||||
|
three macros assembly normally uses instead:
|
||||||
|
|
||||||
|
| Macro | Expands to | Meaning |
|
||||||
|
|---|---|---|
|
||||||
|
| `GO_ARGS` | `FUNCDATA $FUNCDATA_ArgsPointerMaps, go_args_stackmap(SB)` | the Go prototype defines the argument pointer map |
|
||||||
|
| `GO_RESULTS_INITIALIZED` | `PCDATA $PCDATA_StackMapIndex, $1` | results are initialised; treat them as live from here |
|
||||||
|
| `NO_LOCAL_POINTERS` | `FUNCDATA $FUNCDATA_LocalsPointerMaps, no_pointers_stackmap(SB)` | the frame holds no pointers |
|
||||||
|
|
||||||
|
`GO_ARGS` is inserted implicitly by the assembler for any function whose
|
||||||
|
package-qualified name belongs to the current package, which is why most
|
||||||
|
assembly never writes it. `NOSPLIT` leaf functions that call nothing need
|
||||||
|
none of the three.
|
||||||
|
|
||||||
|
The underlying ids, for reading toolchain output rather than for writing
|
||||||
|
source: FUNCDATA 0 to 7 are args pointer maps, locals pointer maps, stack
|
||||||
|
objects, inline tree, open-coded defer info, argument info, argument
|
||||||
|
liveness and wrap info; PCDATA 0 to 4 are unsafe point, stack map index,
|
||||||
|
inline tree index, argument liveness index and panic bounds.
|
||||||
|
|
||||||
|
## What the runtime does with all of this
|
||||||
|
|
||||||
|
The object file records the annotations as aux symbols and FuncInfo records;
|
||||||
|
GOOBJ.md specifies the encoding. The linker assembles them into the runtime's
|
||||||
|
pclntable, which traceback and the collector consume. An assembly function
|
||||||
|
that misdeclares its frame is not a compile error and usually not a link
|
||||||
|
error: it is a wrong collector decision or a wrong traceback at runtime,
|
||||||
|
which is why the annotations are a contract and not documentation.
|
||||||
Reference in New Issue
Block a user