Documentation
¶
Index ¶
- Variables
- func AlternativeOperands(asmTemplate string) map[int]bool
- func ApplyParsedIForm(instr *ir.InstructionIR, p *ParsedIForm)
- func ApplySelectorConstraints(params []Param)
- func AsmMnemonic(asmTemplate string) string
- func DiscoverAliasEncodings(specDir string, canonicalFiles map[string]struct{}, ...) ([]*ir.InstructionIR, error)
- func DiscoverAliasEncodingsCorpus(corpus XMLCorpus, canonicalFiles map[string]struct{}, ...) ([]*ir.InstructionIR, error)
- func ExpandWidthCases(params []Param) [][]Param
- func ExplanationsFor(all []AsmExplanation, encodingID string) map[string]AsmExplanation
- func InferOperandType(name string) ir.OperandType
- func LiteralBits(s string) (string, bool)
- func MarkOptional(asmTemplate string, params []Param, ops []AsmOperand, ...)
- func MethodName(mnemonic string) string
- func NewBitfieldHandler() parse.Handler
- func NewFeatureHandler() parse.Handler
- func NewInstructionRowHandler() parse.Handler
- func NewInstructionTableHandler() parse.Handler
- func NewMnemonicHandler() parse.Handler
- func OrdinalMember(prose string) bool
- func ParseBitDiffs(expr string) (*ir.BitDiffNode, error)
- func RegisterName(class OperandClass, n uint64) string
- type ARMParser
- func (ap *ARMParser) AsmSurface() *AsmSurface
- func (ap *ARMParser) Close(timeout time.Duration) error
- func (ap *ARMParser) DisasmSurface() *DisasmSurface
- func (ap *ARMParser) GetMetrics() map[string]interface{}
- func (ap *ARMParser) GetRegistry() *InstructionRegistry
- func (ap *ARMParser) Parse(ctx context.Context) error
- func (ap *ARMParser) ResolvedInstructions() []*ir.InstructionIR
- type ARMParserConfig
- type AddressingMode
- type AliasEncoding
- type Arch
- type ArityGroup
- type ArrCase
- type ArrDispatch
- type ArrRow
- type ArrSpec
- type AsmExplanation
- type AsmForm
- type AsmOperand
- type AsmSurface
- type BitPart
- type Bitfield
- type BitfieldHandler
- type Catalog
- type CatalogClass
- type CatalogEntry
- type CatalogField
- type ClassEncoderData
- type ClassEncoderRef
- type ClassifiedOperand
- type CodeGenerator
- func (cg *CodeGenerator) GenerateDecoders(ctx context.Context, byClass map[string][]*ir.InstructionIR) error
- func (cg *CodeGenerator) GenerateEncoders(ctx context.Context, byClass map[string][]*ir.InstructionIR) error
- func (cg *CodeGenerator) GenerateRegistry(ctx context.Context, instructions []*ir.InstructionIR) error
- func (cg *CodeGenerator) GenerateRust(catalog *Catalog) error
- func (cg *CodeGenerator) GenerateTests(ctx context.Context, instructions []*ir.InstructionIR) error
- func (cg *CodeGenerator) SetAsmSurface(s *AsmSurface)
- func (cg *CodeGenerator) SetDisasmSurface(s *DisasmSurface)
- type CodegenLang
- type ConstraintData
- type DecoderData
- type DerivedRel
- type DirectoryXMLCorpus
- type DisasmFieldEquality
- type DisasmFieldInequality
- type DisasmForbidden
- type DisasmForm
- type DisasmFormulaExpr
- type DisasmKind
- type DisasmLogicalMoveGuard
- type DisasmMoveWideZeroGuard
- type DisasmOperand
- type DisasmPart
- type DisasmRow
- type DisasmSkip
- type DisasmSurface
- type Disassembly
- type EnumDispatch
- type EnumSpec
- type ExactEncoding
- type FeatureHandler
- type FixedBitData
- type GoConformanceCase
- func EmitGoConformanceTest(modulePath string, catalog *Catalog) (string, []GoConformanceCase)
- func EmitGoConformanceTestFor(modulePath string, catalog *Catalog, disasm *DisasmSurface) (string, []GoConformanceCase)
- func GoConformanceCases(catalog *Catalog) []GoConformanceCase
- func GoConformanceCasesFor(catalog *Catalog, disasm *DisasmSurface) []GoConformanceCase
- type GoConformanceField
- type InstructionEncoderData
- type InstructionRegistry
- func (r *InstructionRegistry) Add(instr *ir.InstructionIR) error
- func (r *InstructionRegistry) BestMatch(word uint32) (*ir.InstructionIR, bool)
- func (r *InstructionRegistry) Disassemble(word uint32) (*Disassembly, bool)
- func (r *InstructionRegistry) GetAll() []*ir.InstructionIR
- func (r *InstructionRegistry) GetByClass(class string) []*ir.InstructionIR
- func (r *InstructionRegistry) GetByEncodingID(encodingID string) (*ir.InstructionIR, bool)
- func (r *InstructionRegistry) GetByFeature(feature string) []*ir.InstructionIR
- func (r *InstructionRegistry) GetByMnemonic(mnemonic string) []*ir.InstructionIR
- func (r *InstructionRegistry) GetClasses() []string
- func (r *InstructionRegistry) GetFeatures() []string
- func (r *InstructionRegistry) GetMnemonics() []string
- func (r *InstructionRegistry) GroupByClass() map[string][]*ir.InstructionIR
- func (r *InstructionRegistry) GroupByFeature() map[string][]*ir.InstructionIR
- func (r *InstructionRegistry) MatchWord(word uint32) []*ir.InstructionIR
- func (r *InstructionRegistry) ResolvedCount() int
- func (r *InstructionRegistry) Size() int
- func (r *InstructionRegistry) Statistics() RegistryStats
- type InstructionRowContext
- type InstructionRowHandler
- type InstructionTableContext
- type InstructionValidator
- type MasterDispatchEntry
- type MasterEncoderData
- type MnemonicHandler
- type ModeVariant
- type OperandClass
- type OperandEncoderData
- type Param
- func TypedParams(ops []AsmOperand) (params []Param, ok bool)
- func TypedParamsFor(asmTemplate string, ops []AsmOperand, exps map[string]AsmExplanation) ([]Param, string)
- func TypedParamsReason(ops []AsmOperand, exps map[string]AsmExplanation) ([]Param, string)
- func TypedParamsWith(ops []AsmOperand, exps map[string]AsmExplanation) (params []Param, ok bool)
- type ParsedIForm
- type ParsedIFormCache
- func (c *ParsedIFormCache) Clear()
- func (c *ParsedIFormCache) GetOrLoad(path, encodingID string) (*ParsedIForm, error)
- func (c *ParsedIFormCache) GetOrLoadCorpus(corpus XMLCorpus, name, encodingID string) (*ParsedIForm, error)
- func (c *ParsedIFormCache) Hits() int64
- func (c *ParsedIFormCache) Misses() int64
- type Placement
- type PseudocodeParser
- type RawEncoding
- type RawField
- type RegBox
- type RegRange
- type RegistryStats
- type RustConformanceCase
- func EmitRustConformanceTest(crateName string, s *AsmSurface) (string, []RustConformanceCase)
- func EmitRustExactConformanceTest(crateName string, s *AsmSurface) (string, []RustConformanceCase)
- func EmitRustExactConformanceTestFor(crateName string, s *AsmSurface, disasm *DisasmSurface) (string, []RustConformanceCase)
- type SymbolValue
- type TarXMLCorpus
- func LoadTarXMLCorpus(r io.Reader, source string) (*TarXMLCorpus, error)
- func LoadTarXMLCorpusWithOptions(r io.Reader, source string, options TarXMLCorpusOptions) (*TarXMLCorpus, error)
- func OpenTarXMLCorpus(ctx context.Context, location string) (*TarXMLCorpus, error)
- func OpenTarXMLCorpusWithOptions(ctx context.Context, location string, options TarXMLCorpusOptions) (*TarXMLCorpus, error)
- type TarXMLCorpusOptions
- type TarXMLCorpusStats
- type ValidationError
- type ValueChoice
- type WidthCase
- type XMLCorpus
Constants ¶
This section is empty.
Variables ¶
Functions ¶
func AlternativeOperands ¶
AlternativeOperands marks the operands that are alternative spellings of an earlier one rather than operands of their own.
ARM writes a choice as "DSB (<option>|#<imm>)": both name the same field, and only one is written at a call site. The first spelling becomes the typed method; the numeric alternative stays available through the exact encoder.
func ApplyParsedIForm ¶
func ApplyParsedIForm(instr *ir.InstructionIR, p *ParsedIForm)
ApplyParsedIForm merges ParsedIForm into InstructionIR (authoritative encoding).
func ApplySelectorConstraints ¶
func ApplySelectorConstraints(params []Param)
ApplySelectorConstraints intersects shared operand tables with conditions on parenthesized alternatives. In "[Xn, (Wm|Xm){, extend}]", Wm fixes option<0> to zero, so LSL/SXTX are not legal rows for that concrete form.
func AsmMnemonic ¶
AsmMnemonic extracts the assembler mnemonic from an asmtemplate.
The registry's Mnemonic field is a *group* name — CRC32CB, CRC32CH and CRC32CW all carry "CRC32C", and LDUMINH/LDUMINLH/LDUMINAH all carry "LDUMINH". Naming methods from it would merge distinct instructions. The asmtemplate's leading literal is the actual assembler spelling.
func DiscoverAliasEncodings ¶
func DiscoverAliasEncodings(specDir string, canonicalFiles map[string]struct{}, classOf func(iformFile string) string) ([]*ir.InstructionIR, error)
DiscoverAliasEncodings returns partial IR for every alias encoding in the spec.
Pass 1 builds its registry from encodingindex.xml, which lists canonical encodings only. Without this step aliases — ASR_ASRV_32_dp_2src, BFC_BFM_32M_bitfield, AT_SYS_CR_systeminstrs and 285 others — never reach the catalog at all, even though ARM marks many of them as the preferred disassembly.
canonicalFiles holds the iform files pass 1 already claimed. Alias pages are exactly the indexed files that are not among them, so the whole spec tree never has to be scanned to find them.
func DiscoverAliasEncodingsCorpus ¶
func DiscoverAliasEncodingsCorpus(corpus XMLCorpus, canonicalFiles map[string]struct{}, classOf func(iformFile string) string) ([]*ir.InstructionIR, error)
DiscoverAliasEncodingsCorpus is the source-agnostic alias discovery path. It works identically for an extracted directory and an in-memory tar corpus.
func ExpandWidthCases ¶
ExpandWidthCases turns one parameter list into one per register width a width-specifier position accepts. Lists with no such position come back unchanged; more than one is not expanded, since the product would multiply impls without a caller ever needing it.
func ExplanationsFor ¶
func ExplanationsFor(all []AsmExplanation, encodingID string) map[string]AsmExplanation
ExplanationsFor returns the explanations that apply to encodingID, keyed by operand symbol. When an explanation lists no encodings it applies to all.
func InferOperandType ¶
func InferOperandType(name string) ir.OperandType
InferOperandType maps ARM field/operand names to OperandType. Cherry-picked from improved-parser-design encoding_handlers.inferOperandTypeFromName and arm-encoding-parser operand_parser heuristics.
func LiteralBits ¶
LiteralBits returns the constant bits of a field-expression item.
func MarkOptional ¶
func MarkOptional(asmTemplate string, params []Param, ops []AsmOperand, exps map[string]AsmExplanation)
MarkOptional flags the operands a caller may leave out.
Braces alone do not decide it. ARM writes both an optional operand ("ADD <Xd>, <Xn>, #<imm>{, <shift>}") and a register list ("LD2B { <Zt1>.B, <Zt2>.B }, ...") in braces, and treating a list's first register as omittable would generate a method that drops a required operand. So the braces locate the candidates and ARM's own prose confirms them: an operand that may be left out always says so, either as "optional" or by naming the value assumed in its absence.
func MethodName ¶
MethodName maps an assembler mnemonic to a snake_case Rust method name.
func NewBitfieldHandler ¶
NewBitfieldHandler creates a handler for bitfield cells
func NewFeatureHandler ¶
NewFeatureHandler creates a handler for feature tags
func NewInstructionRowHandler ¶
NewInstructionRowHandler creates a handler for instruction rows
func NewInstructionTableHandler ¶
NewInstructionTableHandler makes an instruction table's class available to its row handlers through the parser's lexical scope stack.
func NewMnemonicHandler ¶
NewMnemonicHandler creates a handler for mnemonic cells
func OrdinalMember ¶
OrdinalMember reports whether ARM describes an operand by its position in a group — "the name of the second scalable vector register". Together with the operand naming a field an earlier operand already writes, that is ARM saying this one follows from that one: only the first member of a list or pair is encoded.
func ParseBitDiffs ¶
func ParseBitDiffs(expr string) (*ir.BitDiffNode, error)
ParseBitDiffs parses an ARM encoding@bitdiffs expression into a boolean tree. Supported forms (observed in A-profile XML):
sf == 0
cc == 110
A == 1 && R == 0
imm5 == x1000
Rm != 11111
op2 IN {'00x', '010'}
!(op1 == '000' && op2 IN {'00x', '010'})
func RegisterName ¶
func RegisterName(class OperandClass, n uint64) string
RegisterName spells one register of a bank. Register 31 is the case that matters: the same five bits read as wzr/xzr in most positions and as wsp/sp in the positions ARM types "or stack pointer", and the two are different registers.
Types ¶
type ARMParser ¶
type ARMParser struct {
// contains filtered or unexported fields
}
ARMParser orchestrates the 3-pass parsing pipeline
func NewARMParser ¶
func NewARMParser(config ARMParserConfig) *ARMParser
NewARMParser creates a new ARM parser with the given configuration
func (*ARMParser) AsmSurface ¶
func (ap *ARMParser) AsmSurface() *AsmSurface
AsmSurface projects the resolved corpus into the typed assembler model. It is valid after Parse and is exposed for conformance tooling that must call the exact same overloads Pass 3 emitted.
func (*ARMParser) DisasmSurface ¶
func (ap *ARMParser) DisasmSurface() *DisasmSurface
DisasmSurface projects resolved IR into the print model. Valid after Parse.
func (*ARMParser) GetMetrics ¶
GetMetrics returns parsing metrics
func (*ARMParser) GetRegistry ¶
func (ap *ARMParser) GetRegistry() *InstructionRegistry
GetRegistry returns the instruction registry
func (*ARMParser) ResolvedInstructions ¶
func (ap *ARMParser) ResolvedInstructions() []*ir.InstructionIR
ResolvedInstructions returns the registry entries Pass 2 gave authoritative encoding data, which is the set Pass 3 generates from.
type ARMParserConfig ¶
type ARMParserConfig struct {
// Paths
EncodingIndexPath string
IFormDirectory string
OutputDirectory string
// Corpus replaces EncodingIndexPath/IFormDirectory reads with a logical XML
// source, such as TarXMLCorpus. Entry names remain ARM's relative filenames.
Corpus XMLCorpus
// Performance
IFormWorkers int
// IFormCacheSize bounds retained parsed forms. Zero keeps every form for
// the parser's lifetime, which is the efficient default for code generation:
// Pass 3 consumes the same forms Pass 2 just parsed.
IFormCacheSize int
// Features
EnabledFeatures map[string]bool
GenerateTests bool
SkipCodegen bool // when true, stop after Pass 2
MaxIForms int // if >0, resolve at most this many iforms
// Languages selects Pass 3 targets (default: go). Use go, rust, or both.
Languages []CodegenLang
// Arch is the target architecture. It names the generated artifact — the
// Rust crate and Go module are both named after it.
Arch Arch
// Progress receives human-readable pipeline diagnostics. Nil keeps the
// library silent.
Progress io.Writer
}
ARMParserConfig configures the ARM parser
type AddressingMode ¶
type AddressingMode string
AddressingMode is the memory operand form an encoding accepts.
const ( AddrNone AddressingMode = "" // no memory operand AddrBase AddressingMode = "base" // [Xn] AddrOffset AddressingMode = "offset" // [Xn, #imm] AddrPre AddressingMode = "pre" // [Xn, #imm]! AddrPost AddressingMode = "post" // [Xn], #imm AddrRegOff AddressingMode = "reg_off" // [Xn, Xm{, extend}] )
type AliasEncoding ¶
type AliasEncoding struct {
EncodingID string
Mnemonic string // preferred disassembly (docvar alias_mnemonic)
Canonical string // docvar mnemonic: the instruction being aliased
IFormFile string
RefIForm string // <aliasto refiform>: iform file of the canonical encoding
}
AliasEncoding is one <encoding> inside an alias iform page.
type Arch ¶
type Arch string
Arch is a target architecture. It names the instruction set the generated code encodes, and it names the generated artifact: a Rust crate or Go module generated for aarch64 is called "aarch64", so pointing -output at a tree like iasm/arch/aarch64 produces a crate that matches the directory it lands in.
const ( // ArchAArch64 is the ARM A64 instruction set. ArchAArch64 Arch = "aarch64" )
func SupportedArches ¶
func SupportedArches() []Arch
SupportedArches lists the architectures this build can generate.
func (Arch) ArtifactName ¶
ArtifactName is the Rust crate name and Go module name for this target.
func (Arch) SpecIndexFile ¶
SpecIndexFile is the index file the architecture's spec tree is rooted at.
type ArityGroup ¶
ArityGroup is the set of forms sharing one method name: Rust cannot overload on parameter count, so each distinct arity of a mnemonic gets its own method.
func GroupByArity ¶
func GroupByArity(name string, forms []AsmForm) []ArityGroup
GroupByArity buckets a mnemonic's forms into the methods that will be emitted.
A form with optional trailing operands appears in two buckets — its required arity and its full arity — so `add(rd, rn, imm)` and `add_shift(rd, rn, imm, shift)` are both reachable.
The bare mnemonic goes to the bucket holding the most forms rather than the smallest arity: `LDR` has a dozen two-operand forms and one one-operand SME form, and the SME outlier must not claim the name `ldr`.
Both the instruction emitter and the test emitter resolve names here so they cannot drift apart.
type ArrCase ¶
type ArrCase struct {
// Symbol is the assembler spelling, e.g. "8B" or "S".
Symbol string
// Or is the value to OR into the word for this arrangement.
Or uint32
}
ArrCase is one legal arrangement of a form, resolved to the bits it sets.
type ArrDispatch ¶
type ArrDispatch struct {
Param string
// Mask covers every bit the arrangement controls, so the fixed word's bits
// there can be cleared before the arrangement's value is applied.
Mask uint32
Cases []ArrCase
// bits must agree rather than being written twice.
Shared uint32
// Lead names the local holding the earlier operand's selected bits.
Lead string
}
ArrDispatch is the arrangement match emitted for one sized register operand.
type ArrSpec ¶
ArrSpec is an operand's arrangement table: the fields the arrangement spans and one row per legal spelling.
type AsmExplanation ¶
type AsmExplanation struct {
// Symbol is the operand placeholder, e.g. "<T>" or "<Xn|SP>".
Symbol string
// Link is ARM's operand-class id.
Link string
// Fields are the bit fields the operand encodes into, in order. "size:Q"
// yields ["size", "Q"].
Fields []string
// Prose is ARM's description.
Prose string
// Values is the value table for enumerated operands, empty otherwise.
Values []SymbolValue
// ValueFields are the table's own selector columns. They can be narrower
// than Fields: EXT is encoded in Q:imm4, but its legality table selects on
// Q and imm4[3]. Keeping both prevents a one-bit row pattern from being
// compared with the entire four-bit field.
ValueFields []string
// Encodings lists the encoding IDs this explanation applies to.
Encodings []string
}
AsmExplanation is ARM's authoritative description of one operand symbol for a set of encodings, from the <explanations> section of an instruction page.
This is a better operand source than the asmtemplate hover text: 99.7% of explanation blocks state the encoding field in `encodedin`, including multi-field placements like "size:Q" and "immh:immb", and enumerated operands carry a value table mapping bit combinations to their assembler spelling (size:Q = 00:0 -> 8B, cond = 0000 -> EQ).
type AsmForm ¶
type AsmForm struct {
Method string
EncodingID string
Mnemonic string
AsmSyntax string
FixedWord uint32
Pattern string
Params []Param
Tuple []string
Placements []Placement
Mode AddressingMode
IsAlias bool
AliasOf string
// ModeVariants holds sibling encodings that share this form's parameter
// types and differ only in addressing mode: `ldr x0,[x1],#8` (post),
// `ldr x0,[x1,#8]!` (pre) and `ldr x0,[x1,#8]` (offset) are one Rust
// method that matches on the Mem operand's mode.
ModeVariants []ModeVariant
// RequiredArity is how many leading parameters are mandatory; the rest are
// optional operands the plain method omits.
RequiredArity int
// Arrangements is the arrangement dispatch for sized vector operands.
Arrangements []ArrDispatch
// Enums is the dispatch for enumerated operands.
Enums []EnumDispatch
// BaseISA marks a base or SIMD&FP encoding rather than an SVE or SME one.
//
// ARM capitalises base and SIMD&FP encoding ids ("ADR_only_pcreladdr") and
// writes SVE and SME ones in lower case ("adr_z_az_sd_same_scaled"). That
// holds for every encoding in the spec — no iclass mixes the two — so it is
// a reliable way to let the common scalar form keep the bare method name
// when an SVE form of the same mnemonic has more operands.
BaseISA bool
}
AsmForm is one concrete operand shape of one mnemonic: exactly one Rust trait impl, encoding exactly one ARM encoding.
type AsmOperand ¶
type AsmOperand struct {
// Symbol is the placeholder as written, e.g. "<Xn|SP>" or "<T>".
Symbol string
// Link is ARM's operand-class id, e.g. "XnSP_option". Stable across
// instructions, so it groups operands that share a type.
Link string
// Hover is ARM's prose description of the operand.
Hover string
// Field is the bit field Hover names ("encoded in the \"Rn\" field"),
// empty when the prose does not state one.
Field string
// Prefix is the literal template text between the previous operand and this
// one, kept untrimmed. It is the only thing that distinguishes "SADDLV
// <V><d>" — where <V> is a width specifier sizing <d> — from "SSHR D<d>",
// where the width is a literal. Empty means the two operands are adjacent.
Prefix string
}
AsmOperand is one operand reference from an encoding's asmtemplate.
type AsmSurface ¶
type AsmSurface struct {
// Methods maps a Rust method name to its overload set (one trait impl each).
Methods map[string][]AsmForm
// MethodOrder is Methods' keys, sorted, for deterministic output.
MethodOrder []string
// Exact holds one field-level encoder per ARM encoding, in id order.
Exact []ExactEncoding
// Raw holds encodings with no typed signature, reachable via the exact API.
Raw []RawEncoding
// Enums are the generated value-table types, keyed by Rust type name.
Enums map[string]*EnumSpec
// Dropped records encodings excluded from every surface, with the reason.
Dropped map[string]string
}
AsmSurface is the whole generated assembler API.
func BuildAsmSurface ¶
func BuildAsmSurface(instrs []*ir.InstructionIR, load func(*ir.InstructionIR) *ParsedIForm) *AsmSurface
BuildAsmSurface projects resolved IR into the typed assembler API plus the field-level encoders that make every encoding reachable exactly.
type BitPart ¶
type BitPart struct {
Field string
Start, End int
Width int
// Literal holds the constant bits when this part is not a field: the base
// register of a strided multi-vector group is "T:'00':Zt", and a register
// outside that group is simply not encodable here.
Literal string
IsLit bool
}
BitPart is one field a split value occupies, or a run of constant bits the value must contain.
type BitfieldHandler ¶
type BitfieldHandler struct {
// contains filtered or unexported fields
}
BitfieldHandler handles <td class="bitfield"> elements
func (*BitfieldHandler) End ¶
func (h *BitfieldHandler) End() parse.HandlerFunc
func (*BitfieldHandler) Selector ¶
func (h *BitfieldHandler) Selector() parse.Selector
func (*BitfieldHandler) Start ¶
func (h *BitfieldHandler) Start() parse.HandlerFunc
type Catalog ¶
type Catalog struct {
Entries []CatalogEntry
Classes []CatalogClass
}
Catalog is the language-agnostic Pass 3 model shared by Go and Rust emitters.
func BuildCatalog ¶
func BuildCatalog(instructions []*ir.InstructionIR) *Catalog
BuildCatalog projects resolved IR into the shared codegen model.
type CatalogClass ¶
type CatalogClass struct {
Name string
TypeName string // Go exported type stem
FieldName string // Go struct field
Entries []CatalogEntry
}
CatalogClass groups encodings by IClass for per-class encoder files (Go).
type CatalogEntry ¶
type CatalogEntry struct {
EncodingID string
Mnemonic string
Class string
Pattern string
AliasOf string
Asm string
IFormFile string
Mask uint32
Value uint32
FixedWord uint32
HasFixed bool
Fields []CatalogField
BitDiffs *ir.BitDiffNode
}
CatalogEntry is one encoding ready for encode/decode/registry emission.
type CatalogField ¶
type CatalogField struct {
Name string
Start, End int
Fixed bool
// Free marks the bits inside [Start,End] that the encoding leaves variable,
// as absolute bit positions. A field can be partly pinned — SMSTOP pins
// CRm<0> to 0 while CRm<2:1> vary — so writing the whole range blind
// produces a word belonging to a different encoding.
Free uint32
}
CatalogField is a named bitfield layout.
type ClassEncoderData ¶
type ClassEncoderData struct {
Package string
ClassName string
Instructions []InstructionEncoderData
Imports []string
}
type ClassEncoderRef ¶
type ClassifiedOperand ¶
type ClassifiedOperand struct {
AsmOperand
Class OperandClass
// ResolvedField is the first field this operand encodes into. Empty means
// the operand cannot be placed.
ResolvedField string
// Fields holds every field the operand spans, as ARM's `encodedin` lists
// them. Length > 1 means the value does not live in a single field.
Fields []string
// Split holds the fields in the order the value's bits occupy them, most
// significant first, and is set only when ARM's prose states that the value
// is simply the concatenation of those fields.
//
// The order comes from the prose, not from `encodedin`: TBZ's bit number is
// `encodedin="b40:b5"` but reads "encoded in \"b5:b40\"", and the logical
// immediate is `encodedin="immr:imms"` but reads "imms:immr". Taking the
// attribute order would transpose the halves of both.
Split []string
// Algorithmic marks an operand that spans several fields by a computation
// rather than a concatenation — a bitmask immediate, a shift amount encoded
// as 128 - UInt(immh:immb), an element index folded together with its
// element size. Placing such a value by concatenation encodes the wrong
// word, so these are not given an operand-typed signature.
Algorithmic bool
// Explanation is ARM's entry for this operand, including any value table.
Explanation AsmExplanation
// Range is the inclusive value range for immediates when ARM states one.
Lo, Hi int64
HasRange bool
// RegLo/RegHi bound a register operand ARM restricts to part of its bank:
// "the vector select register W12-W15", "predicate register P0-P7". Without
// them a caller could pass W0 and have the field silently truncate.
RegLo, RegHi int64
HasRegRange bool
// RegMultiple restricts a register number to a stated alignment. Pair
// instructions use 2 for the first even-numbered register.
RegMultiple int64
// RegRanges maps disjoint written register runs into one consecutive field.
RegRanges []RegRange
// Default is the encoded value when the operand is omitted.
Default int64
HasDefault bool
// DefaultSymbol is the assembler spelling of an omitted table operand,
// such as SVE's ALL pattern.
DefaultSymbol string
// Mirrors are additional whole fields that receive this operand's value.
Mirrors []string
// InvertLSB is ARM's <invcond> alias transformation.
InvertLSB bool
// Scale is the encoding multiplier: a byte offset of 8 held in a scaled
// imm12 encodes as 1, and a multi-vector group base written Z4 encodes as 2.
// 1 when unscaled.
Scale int64
// Bias is what the encoding subtracts from the written value before storing
// it: "encoded as \"imm6\" plus 1" holds value-1. Negative adds.
Bias int64
// Negate is set when the field counts down from a constant: a right shift
// "encoded as 128 - UInt(immh:immb)" is held as 128 minus the amount.
Negate int64
// Derived is how a ClassDerived operand's value follows from the encoding.
// The assembler must not accept such an operand — supplying it could only
// introduce an inconsistency — but a disassembler still has to print it.
Derived *DerivedRel
}
ClassifiedOperand is an AsmOperand resolved to a class and encoding field.
func ClassifyOperand ¶
func ClassifyOperand(o AsmOperand) ClassifiedOperand
ClassifyOperand resolves one asmtemplate operand reference from its hover prose alone. Prefer ClassifyOperandWith, which also consults ARM's <explanations> section.
func ClassifyOperandWith ¶
func ClassifyOperandWith(o AsmOperand, exp AsmExplanation) ClassifiedOperand
ClassifyOperandWith resolves an operand using ARM's <explanations> entry when one is available.
The explanation is the authoritative source: it states the encoding field in `encodedin` for 99.7% of operands — including multi-field placements like "size:Q" and "immh:immb" that the hover prose never mentions — and it carries the value table for enumerated operands.
type CodeGenerator ¶
type CodeGenerator struct {
// contains filtered or unexported fields
}
CodeGenerator generates Go code from the instruction IR
func NewCodeGenerator ¶
func NewCodeGenerator(outputDir string, arch Arch) *CodeGenerator
NewCodeGenerator creates a new code generator
func (*CodeGenerator) GenerateDecoders ¶
func (cg *CodeGenerator) GenerateDecoders(ctx context.Context, byClass map[string][]*ir.InstructionIR) error
GenerateDecoders generates decoder functions
func (*CodeGenerator) GenerateEncoders ¶
func (cg *CodeGenerator) GenerateEncoders(ctx context.Context, byClass map[string][]*ir.InstructionIR) error
GenerateEncoders generates encoder functions grouped by class
func (*CodeGenerator) GenerateRegistry ¶
func (cg *CodeGenerator) GenerateRegistry(ctx context.Context, instructions []*ir.InstructionIR) error
GenerateRegistry generates the instruction registry
func (*CodeGenerator) GenerateRust ¶
func (cg *CodeGenerator) GenerateRust(catalog *Catalog) error
GenerateRust emits a Rust crate for catalog under outputDir.
func (*CodeGenerator) GenerateTests ¶
func (cg *CodeGenerator) GenerateTests(ctx context.Context, instructions []*ir.InstructionIR) error
GenerateTests generates decoder golden tests under decoders/ (package-level).
func (*CodeGenerator) SetAsmSurface ¶
func (cg *CodeGenerator) SetAsmSurface(s *AsmSurface)
SetAsmSurface supplies the typed assembler model for Rust codegen.
func (*CodeGenerator) SetDisasmSurface ¶
func (cg *CodeGenerator) SetDisasmSurface(s *DisasmSurface)
SetDisasmSurface supplies the print model used to choose legal exhaustive conformance representatives for every generated language.
type CodegenLang ¶
type CodegenLang string
CodegenLang is a Pass 3 emission target.
const ( LangGo CodegenLang = "go" LangRust CodegenLang = "rust" )
type ConstraintData ¶
type ConstraintData struct {
OperandName string
Constraint ir.Constraint
}
type DecoderData ¶
type DerivedRel ¶
DerivedRel states a derived operand's value as (field × Mul + Add) mod Mod, or as the constant Const when Field is empty.
These are the only shapes ARM uses: the second register of a pair is "Rt" +1, the second of a list is "Zt" plus 1 modulo 32, the second of a strided multi-vector group is "Zn" times 2 plus 1, and a slice index ARM fixes outright has "implicit value 0".
type DirectoryXMLCorpus ¶
type DirectoryXMLCorpus struct {
// contains filtered or unexported fields
}
func NewDirectoryXMLCorpus ¶
func NewDirectoryXMLCorpus(root string) *DirectoryXMLCorpus
func (*DirectoryXMLCorpus) Description ¶
func (c *DirectoryXMLCorpus) Description() string
func (*DirectoryXMLCorpus) OpenXML ¶
func (c *DirectoryXMLCorpus) OpenXML(name string) (io.ReadCloser, error)
type DisasmFieldEquality ¶
type DisasmFieldEquality struct {
LeftStart, LeftEnd int
RightStart, RightEnd int
// Add is applied to the left value modulo the field width.
Add uint32
}
DisasmFieldEquality says two complete encoding fields must have the same value for an alias spelling to apply.
type DisasmFieldInequality ¶
type DisasmFieldInequality struct {
LeftStart, LeftEnd int
RightStart, RightEnd int
RightMutable uint32
}
DisasmFieldInequality records an architectural register-overlap constraint. RightMutable is the portion of the right field that a representative-word solver may alter without changing fixed opcode bits.
type DisasmForbidden ¶
DisasmForbidden is one conjunction of field values that Decode classifies as UNDEFINED. Mutable contains the non-fixed bits a legal representative can change without leaving the encoding.
type DisasmForm ¶
type DisasmForm struct {
EncodingID string
Mnemonic string
Parts []DisasmPart
// ConstraintMask/Value and EqualFields are the alias predicate that selects
// this spelling. They are part of decoding, not merely sample-generation
// metadata: a word that does not satisfy them must not print as the alias.
ConstraintMask uint32
ConstraintValue uint32
EqualFields []DisasmFieldEquality
UnequalFields []DisasmFieldInequality
// SampleUnequalFields canonicalizes independently assembled probes without
// rejecting allocated constrained-unpredictable words from the formatter.
SampleUnequalFields []DisasmFieldInequality
OneHotMasks []uint32
Forbidden []DisasmForbidden
// SVEMoveMaskField carries the imm13 selected by ARM's
// SVEMoveMaskPreferred alias predicate.
SVEMoveMaskField *BitPart
MoveWideZeroGuard *DisasmMoveWideZeroGuard
LogicalMoveGuard *DisasmLogicalMoveGuard
GroupParent map[int]int
RequiredGroups map[int]bool
PreferOmittedSystemRegister bool
}
DisasmForm is how one encoding prints.
func (*DisasmForm) Render ¶
func (f *DisasmForm) Render(word uint32) (string, bool)
Render prints one decoded word as assembly text.
ok is false when the word does not spell a legal instruction under this form: a value table with no row for the bits present means ARM left that combination unallocated, and there is no text to print.
func (*DisasmForm) SatisfyConstraints ¶
func (f *DisasmForm) SatisfyConstraints(word uint32) (uint32, bool)
SatisfyConstraints returns the nearest word satisfying this form's decoded alias predicate. It is useful when constructing a legal representative of an encoding; Render independently checks the same predicate.
type DisasmFormulaExpr ¶
type DisasmKind ¶
type DisasmKind string
DisasmKind is how an operand slot turns bits into text.
const ( // DisasmReg prints a register name from a bank chosen by the operand class. DisasmReg DisasmKind = "reg" // DisasmNum prints a number, after undoing the encoding's scale/bias/negate. DisasmNum DisasmKind = "num" // DisasmFpImm prints ARM's VFPExpandImm 8-bit constant. DisasmFpImm DisasmKind = "fpimm8" // DisasmSysReg prints the generic architectural S<op0>_<op1>_C... name. DisasmSysReg DisasmKind = "sysreg" // DisasmTable prints the assembler spelling ARM's value table gives for the // bits — a condition code, an element arrangement, a prefetch operation. DisasmTable DisasmKind = "table" // DisasmDerived prints a register whose number follows from another // operand's field: the second of a pair, the second of a list. DisasmDerived DisasmKind = "derived" // DisasmFormula evaluates one of ARM's small decode-table expressions, such // as 64-UInt(immh:immb) or UInt(H:L:M). DisasmFormula DisasmKind = "formula" // DisasmLogicalImm inverts A64's N:immr:imms logical-bitmask encoding. DisasmLogicalImm DisasmKind = "logical-imm" // DisasmBitfieldWidth inverts a BFM/SBFM/UBFM alias width. DisasmBitfieldWidth DisasmKind = "bitfield-width" // DisasmByteMaskImm expands MOVI's a:h selector bits into eight 00/FF bytes. DisasmByteMaskImm DisasmKind = "byte-mask-imm" // DisasmMoveWideImm reconstructs MOV's shifted MOVZ/MOVN alias immediate. DisasmMoveWideImm DisasmKind = "move-wide-imm" // DisasmLiteral prints an operand whose value ARM states directly in prose, // such as the fixed H destination-width specifier on half reductions. DisasmLiteral DisasmKind = "literal" // DisasmElementIndex removes the unary element-size marker from packed // index fields such as imm2:tsz and i1:tszh:tszl. DisasmElementIndex DisasmKind = "element-index" // DisasmTileMask expands ZERO's imm8 mask to a legal list of ZA*.D names. DisasmTileMask DisasmKind = "tile-mask" )
type DisasmLogicalMoveGuard ¶
type DisasmLogicalMoveGuard struct {
SF, N, Imms, Immr BitPart
}
type DisasmMoveWideZeroGuard ¶
type DisasmOperand ¶
type DisasmOperand struct {
Symbol string
Class OperandClass
Kind DisasmKind
// Parts are the bit runs holding the value, most significant first. A
// single-field operand has exactly one.
Parts []BitPart
// Scale, Bias and Negate undo the encoding relation: the printed value is
// Negate-raw when Negate is set, otherwise raw+Bias, then times Scale.
Scale int64
Bias int64
Negate int64
// RawMul applies after decoding signedness/bias and before Scale. A PAC
// immediate label is PC-(UInt(imm16)*4), represented by RawMul=-1.
RawMul int64
Signed bool
RegRanges []RegRange
Lo, Hi int64
HasRange bool
RegLo, RegHi int64
HasRegRange bool
RegMultiple int64
// NumPrefix is assembler syntax attached to a numeric field, such as the
// architectural control-register names C0-C15.
NumPrefix string
// NumConstant is the written value for a presence bit. Register-offset
// byte accesses encode S=0 when the optional "#0" is omitted and S=1 when
// that same value is present; S is not the numeric shift amount.
NumConstant int64
HasNumConstant bool
// WhenMask/Value select one operand from ARM's parenthesized alternative
// syntax, such as (Wm|Xm) selected by option<0>.
WhenMask uint32
WhenValue uint32
// Cols and Rows carry ARM's value table for DisasmTable operands. Each row
// holds one bit pattern per column, in the table's own column order, with
// 'x' as a don't-care.
Cols []BitPart
Rows []DisasmRow
// Formulas aligns with Rows for a formula table. The row selects an
// expression whose Parts are concatenated most-significant first.
Formulas []DisasmFormulaExpr
// FormulaIgnoredZero aligns with formula rows and identifies the portion of
// their parent fields ARM explicitly says is ignored and should be zero.
FormulaIgnoredZero []uint32
// IgnoredShouldZero records ARM's explicit canonical-encoding instruction
// for selector don't-cares.
IgnoredShouldZero bool
MoveWideInvert bool
LogicalInvert bool
// DataSize bounds coupled bitfield alias operands. In a 32-bit extract,
// imms[5] is unallocated even when imms-immr+1 happens to look like a
// plausible width.
DataSize int64
Literal string
// IndexSizeParts is the number of trailing Parts that form the unary size
// selector for DisasmElementIndex.
IndexSizeParts int
// Xor is applied to the encoded selector before its table lookup. Alias
// operands such as <invcond> store cond<0> inverted while printing the
// caller-facing condition.
Xor uint64
// Default is the encoded value that means "omitted". An optional group whose
// operands all read as their default is not printed.
Default int64
HasDefault bool
// Mul, Add and Mod carry the derivation of a DisasmDerived operand, whose
// value is (Parts × Mul + Add) mod Mod, or the constant Add when it has no
// Parts.
Mul, Add, Mod int64
}
DisasmOperand is one operand slot, resolved to the bits it reads from.
type DisasmPart ¶
type DisasmPart struct {
// Literal is emitted verbatim when Op is nil, spacing included.
Literal string
Op *DisasmOperand
// Group is the optional-brace group this part belongs to, 0 for parts that
// always print. ARM writes an omittable operand and its leading separator
// inside one brace group — "[<Xn|SP>{, #<pimm>}]" — so the separator must be
// dropped with the operand it introduces, never on its own.
Group int
}
DisasmPart is one piece of an instruction's printed text.
type DisasmSkip ¶
DisasmSkip is one encoding that cannot be printed, and why.
type DisasmSurface ¶
type DisasmSurface struct {
Forms []DisasmForm
// Skipped names the encodings that have no printable form, with the operand
// and reason that stopped them. It is a census, not a log — a bar can be
// asserted against it.
Skipped []DisasmSkip
}
DisasmSurface is the whole print model: one form per printable encoding.
func BuildDisasmSurface ¶
func BuildDisasmSurface(instrs []*ir.InstructionIR, load func(*ir.InstructionIR) *ParsedIForm) *DisasmSurface
BuildDisasmSurface projects resolved IR into the print model.
type Disassembly ¶
type Disassembly struct {
Instruction *ir.InstructionIR
Word uint32
Fields []ir.FieldValue
// Alternates are other MatchWord hits after the best (may be empty).
Alternates []*ir.InstructionIR
}
Disassemble is BestMatch plus field extraction for the winning encoding.
type EnumDispatch ¶
type EnumDispatch struct {
Param string
Type string
Mask uint32
Cases []ArrCase
Exhaustive bool
DefaultOr uint32
HasDefault bool
}
EnumDispatch is the match emitted for an operand ARM defines by a value table of assembler spellings.
type EnumSpec ¶
type EnumSpec struct {
// Name is the Rust type name, derived from ARM's operand-class link id.
Name string
// Fields are the bit fields the table spans, in ARM's order.
Fields []string
// Rows is one entry per legal spelling.
Rows []ArrRow
}
EnumSpec is a generated Rust enum standing for one ARM value table.
type ExactEncoding ¶
type ExactEncoding struct {
// Fn is the Rust function name, derived from the ARM encoding id.
Fn string
EncodingID string
Mnemonic string
AsmSyntax string
FixedWord uint32
Pattern string
Fields []RawField
// FixedLegal reports whether the zeroed settable fields satisfy this
// encoding's bitdiff constraints. Some exact encoders have no legal zero
// base (for example, SIMD shifts require immh != 0).
FixedLegal bool
// AliasOf names the encoding this one is an alias of, empty when canonical.
AliasOf string
// Typed is true when this encoding also has an operand-typed method.
Typed bool
}
ExactEncoding is the field-level encoder generated for every encoding in the ISA, whether or not its operands could be given a typed signature. It is what makes the crate complete: each of ARM's encodings has one named function that sets exactly its settable fields over its fixed word.
type FeatureHandler ¶
type FeatureHandler struct {
*parse.FuncHandler
}
FeatureHandler handles feature requirements
type FixedBitData ¶
type GoConformanceCase ¶
type GoConformanceCase struct {
EncodingID string
Fields []GoConformanceField
}
GoConformanceCase identifies one generated exact-encoder call.
func EmitGoConformanceTest ¶
func EmitGoConformanceTest(modulePath string, catalog *Catalog) (string, []GoConformanceCase)
EmitGoConformanceTest emits the generated module's exact-encoder ledger.
Ordinary `go test ./...` skips the ledger. The strict external gate enables it, parses "<index>\t<encoding-id>\t<word>", renders each word from the ARM print model, and requires LLVM to reproduce the same bytes.
func EmitGoConformanceTestFor ¶
func EmitGoConformanceTestFor( modulePath string, catalog *Catalog, disasm *DisasmSurface, ) (string, []GoConformanceCase)
func GoConformanceCases ¶
func GoConformanceCases(catalog *Catalog) []GoConformanceCase
GoConformanceCases builds one deterministic, non-zero exact-encoder sample for every encoding in catalog. Values include each field's pinned bits and vary only bits the encoding actually leaves writable.
func GoConformanceCasesFor ¶
func GoConformanceCasesFor(catalog *Catalog, disasm *DisasmSurface) []GoConformanceCase
GoConformanceCasesFor builds exact-encoder probes and, when supplied, uses the print model to choose architecturally legal representatives.
type GoConformanceField ¶
GoConformanceField is one complete field value passed to EncodeWithFields.
type InstructionEncoderData ¶
type InstructionEncoderData struct {
Instruction *ir.InstructionIR
FuncName string
Operands []OperandEncoderData
FixedBits []FixedBitData
Constraints []ConstraintData
}
type InstructionRegistry ¶
type InstructionRegistry struct {
// contains filtered or unexported fields
}
InstructionRegistry stores and indexes parsed instructions
func NewInstructionRegistry ¶
func NewInstructionRegistry() *InstructionRegistry
NewInstructionRegistry creates a new instruction registry
func (*InstructionRegistry) Add ¶
func (r *InstructionRegistry) Add(instr *ir.InstructionIR) error
Add adds an instruction to the registry
func (*InstructionRegistry) BestMatch ¶
func (r *InstructionRegistry) BestMatch(word uint32) (*ir.InstructionIR, bool)
BestMatch returns the most-specific MatchWord hit, if any.
func (*InstructionRegistry) Disassemble ¶
func (r *InstructionRegistry) Disassemble(word uint32) (*Disassembly, bool)
Disassemble matches word and extracts fields for the best encoding.
func (*InstructionRegistry) GetAll ¶
func (r *InstructionRegistry) GetAll() []*ir.InstructionIR
GetAll returns all instructions
func (*InstructionRegistry) GetByClass ¶
func (r *InstructionRegistry) GetByClass(class string) []*ir.InstructionIR
GetByClass retrieves all instructions in a given class
func (*InstructionRegistry) GetByEncodingID ¶
func (r *InstructionRegistry) GetByEncodingID(encodingID string) (*ir.InstructionIR, bool)
GetByEncodingID retrieves an instruction by its encoding ID
func (*InstructionRegistry) GetByFeature ¶
func (r *InstructionRegistry) GetByFeature(feature string) []*ir.InstructionIR
GetByFeature retrieves all instructions requiring a specific feature
func (*InstructionRegistry) GetByMnemonic ¶
func (r *InstructionRegistry) GetByMnemonic(mnemonic string) []*ir.InstructionIR
GetByMnemonic retrieves all instructions with a given mnemonic
func (*InstructionRegistry) GetClasses ¶
func (r *InstructionRegistry) GetClasses() []string
GetClasses returns all unique instruction classes
func (*InstructionRegistry) GetFeatures ¶
func (r *InstructionRegistry) GetFeatures() []string
GetFeatures returns all unique features
func (*InstructionRegistry) GetMnemonics ¶
func (r *InstructionRegistry) GetMnemonics() []string
GetMnemonics returns all unique mnemonics
func (*InstructionRegistry) GroupByClass ¶
func (r *InstructionRegistry) GroupByClass() map[string][]*ir.InstructionIR
GroupByClass returns instructions grouped by class
func (*InstructionRegistry) GroupByFeature ¶
func (r *InstructionRegistry) GroupByFeature() map[string][]*ir.InstructionIR
GroupByFeature returns instructions grouped by required features
func (*InstructionRegistry) MatchWord ¶
func (r *InstructionRegistry) MatchWord(word uint32) []*ir.InstructionIR
MatchWord returns instructions whose BitPattern (or encoding fixed bits) match the given 32-bit instruction word. O(n) scan; use decoder.Match for tree walks. Results are sorted most-specific first (largest fixed-bit mask).
func (*InstructionRegistry) ResolvedCount ¶
func (r *InstructionRegistry) ResolvedCount() int
ResolvedCount returns how many instructions look Pass-2-resolved.
func (*InstructionRegistry) Size ¶
func (r *InstructionRegistry) Size() int
Size returns the number of instructions in the registry
func (*InstructionRegistry) Statistics ¶
func (r *InstructionRegistry) Statistics() RegistryStats
Statistics returns registry statistics
type InstructionRowContext ¶
type InstructionRowContext struct {
EncodingID string
Mnemonic string
IClass string
IFormFile string
Bitfields []Bitfield
Features []string
}
InstructionRowContext holds state during instruction row parsing
type InstructionRowHandler ¶
type InstructionRowHandler struct {
*parse.TypedHandler[*InstructionRowContext, *ir.InstructionIR]
}
InstructionRowHandler handles <tr> elements in encodingindex.xml
type InstructionTableContext ¶
type InstructionTableContext struct {
IClass string
}
type InstructionValidator ¶
type InstructionValidator struct {
// contains filtered or unexported fields
}
InstructionValidator validates instruction IR consistency.
func NewInstructionValidator ¶
func NewInstructionValidator() *InstructionValidator
NewInstructionValidator creates a validator.
func (*InstructionValidator) ErrorCount ¶
func (v *InstructionValidator) ErrorCount() int
ErrorCount returns the number of validation errors.
func (*InstructionValidator) GetErrors ¶
func (v *InstructionValidator) GetErrors() []ValidationError
GetErrors returns a copy of collected errors.
func (*InstructionValidator) Validate ¶
func (v *InstructionValidator) Validate(instr *ir.InstructionIR) bool
Validate checks one instruction. Returns true if no new errors were found.
func (*InstructionValidator) ValidateAll ¶
func (v *InstructionValidator) ValidateAll(instructions []*ir.InstructionIR) int
ValidateAll validates every instruction; returns error count.
type MasterDispatchEntry ¶
type MasterEncoderData ¶
type MasterEncoderData struct {
Package string
Classes []ClassEncoderRef
Dispatches []MasterDispatchEntry
}
type MnemonicHandler ¶
type MnemonicHandler struct {
*parse.FuncHandler
}
MnemonicHandler handles <td class="iformname"> elements
type ModeVariant ¶
type ModeVariant struct {
Mode AddressingMode
EncodingID string
FixedWord uint32
Pattern string
Placements []Placement
}
ModeVariant is one addressing-mode alternative of a form.
type OperandClass ¶
type OperandClass string
OperandClass is the semantic type of an assembler operand, derived from ARM's own operand prose and operand-class link ids rather than guessed from names.
const ( ClassGpr32 OperandClass = "gpr32" // W0-W30, WZR ClassGpr32Sp OperandClass = "gpr32sp" // W0-W30, WSP ClassGpr64 OperandClass = "gpr64" // X0-X30, XZR ClassGpr64Sp OperandClass = "gpr64sp" // X0-X30, SP ClassSimdB OperandClass = "simdb" ClassSimdH OperandClass = "simdh" ClassSimdS OperandClass = "simds" ClassSimdD OperandClass = "simdd" ClassSimdQ OperandClass = "simdq" ClassSimdVec OperandClass = "simdvec" // <Vd>.<T> ClassSveZ OperandClass = "svez" ClassSveP OperandClass = "svep" ClassSvePN OperandClass = "svepn" // SME predicate-as-counter PN8-PN15 ClassSmeTile OperandClass = "smetile" // <ZAda>, <ZAn>: ZA0-ZA15 ClassImm OperandClass = "imm" // ClassFpImm is ARM's VFPExpandImm 8-bit floating-point constant. It is // deliberately distinct from a numeric immediate: the field stores the // compact FP encoding, not the integer value written after '#'. ClassFpImm OperandClass = "fpimm8" ClassLabel OperandClass = "label" ClassCond OperandClass = "cond" ClassSysReg OperandClass = "sysreg" ClassShift OperandClass = "shift" // LSL/LSR/ASR/ROR selector ClassExtend OperandClass = "extend" // UXTB…SXTX selector // ClassEnum is an operand ARM defines by a value table of assembler // spellings that is not a register arrangement: prefetch operations, SVE // count patterns, index-extend modifiers, slice direction. Each becomes a // generated Rust enum whose variants are exactly ARM's spellings. ClassEnum OperandClass = "enum" // ClassArrangement is a type modifier, not a parameter: <T> selects the // element arrangement of the register operand it attaches to. ClassArrangement OperandClass = "arrangement" // ClassDerived is an operand whose value is fixed by another operand: the // second register of a pair or list, or the end of a slice range. It // contributes no parameter because supplying it could only introduce an // inconsistency the assembler would have to reject. ClassDerived OperandClass = "derived" // ClassUnsupported marks operands this generator will not place on a guess. ClassUnsupported OperandClass = "unsupported" )
type OperandEncoderData ¶
type Param ¶
type Param struct {
// Name is the Rust parameter name, derived from the ARM operand symbol.
Name string
// RustType is the parameter's Rust type.
RustType string
// Field is the encoding bit field this parameter lands in.
Field string
// Split names the fields the value spans, most significant first, when it
// does not fit in one field. Empty for the ordinary single-field case.
Split []string
Class OperandClass
// Arrangement is true when a size specifier attaches to this register
// operand, making the element arrangement part of the operand rather than a
// parameter of its own.
Arrangement bool
// Arr carries ARM's arrangement table when the operand is sized by a <T>
// specifier: which spellings are legal and what bits each one sets. Without
// it the size and Q fields would be left at zero and the encoding would be
// wrong for every arrangement but the first.
Arr *ArrSpec
// ArrDispatch is Arr resolved against one encoding's field layout: the mask
// the arrangement controls and the bits each spelling sets.
ArrDispatch *ArrDispatch
// ArrSymbol is the specifier that sized this operand: <T>, <Ta>, <Tb>. A
// narrowing instruction writes different specifiers on different operands
// (ADDHNB <Zd>.<T>, <Zn>.<Tb>), and they are not interchangeable.
ArrSymbol string
// Enum is the generated Rust enum for an operand ARM defines by a table of
// assembler spellings — a prefetch operation, an SVE count pattern.
Enum *EnumSpec
// WidthCases expands this operand into one form per register width, for the
// positions where ARM writes the width as a specifier over a field rather
// than in the operand's own name: "ADD <Xd|SP>, <Xn|SP>, <R><m>" takes a W
// or an X register, selected by the "option" field. One Rust method with two
// impls is the faithful rendering; a single type would silently accept one
// width and encode the other.
WidthCases []WidthCase
// WidthFields and WidthBits are the chosen case after expansion: the fields
// the specifier occupies, and the bits this variant sets in them.
WidthFields []string
WidthBits []string
// Lo/Hi/Scale carry ARM's stated immediate range and encoding multiplier.
Lo, Hi int64
HasRange bool
Scale int64
// RegLo/RegHi restrict a register operand to part of its bank, and Bias is
// what the encoding subtracts: the SME vector-select register is written
// W12-W15 and encoded in a 2-bit field as v-12.
RegLo, RegHi int64
HasRegRange bool
RegMultiple int64
RegRanges []RegRange
// Bias is what the encoding subtracts before storing the value.
Bias int64
// Negate is set when the field counts down from a constant.
Negate int64
// Default is the value ARM specifies when the operand is omitted, e.g.
// RET's <Xn> "Defaults to X30 if absent". Leaving it out would silently
// encode Rn = 0, making `ret()` mean `ret x0`.
Default int64
HasDefault bool
DefaultSymbol string
// Choices retains the legal rows for a shared built-in operand type. A
// register-offset form accepts UXTW/LSL/SXTW/SXTX, for example, rather than
// every value in the global Extend enum.
Choices []ValueChoice
// Selector records ARM prose such as "option<0> is set to 0" on a
// parenthesized register alternative. It constrains any operand table that
// owns the same field.
SelectorField string
SelectorBit int
SelectorValue uint32
HasSelector bool
Mirrors []string
InvertLSB bool
// Optional is true when the asmtemplate wraps this operand in braces:
// "ADD <Xd|SP>, <Xn|SP>, #<imm>{, <shift>}". Rust has no default arguments,
// so the plain method omits optional trailing operands and a suffixed
// variant accepts them.
Optional bool
}
Param is one parameter of a generated typed assembler method.
func TypedParams ¶
func TypedParams(ops []AsmOperand) (params []Param, ok bool)
TypedParams converts an encoding's asmtemplate operands into typed Rust parameters. ok is false when any operand cannot be typed or placed, in which case the encoding is reachable only through the field-level API.
func TypedParamsFor ¶
func TypedParamsFor(asmTemplate string, ops []AsmOperand, exps map[string]AsmExplanation) ([]Param, string)
TypedParamsFor is TypedParamsReason with the asmtemplate, which is needed to recognise ARM's alternation syntax.
func TypedParamsReason ¶
func TypedParamsReason(ops []AsmOperand, exps map[string]AsmExplanation) ([]Param, string)
TypedParamsReason is TypedParamsWith with the reason the operands could not be typed, so the gap between "typed" and "exact only" is attributable per encoding rather than reported as one bucket.
func TypedParamsWith ¶
func TypedParamsWith(ops []AsmOperand, exps map[string]AsmExplanation) (params []Param, ok bool)
TypedParamsWith converts operands to Rust parameters using ARM's <explanations> entries for field binding and enumerated value tables.
type ParsedIForm ¶
type ParsedIForm struct {
EncodingName string
Mnemonic string
// AliasMnemonic is the preferred disassembly on an alias page (docvar
// alias_mnemonic), e.g. ASR for the ASRV encoding it aliases.
AliasMnemonic string
// AsmTemplate is the encoding's syntax exactly as ARM writes it, spacing
// included: "LDR <Wt>, [<Xn|SP>{, #<pimm>}]". Whitespace is load-bearing —
// it is what separates the mnemonic from its first operand when the text is
// printed back out.
AsmTemplate string
// AsmSuffix is the literal template text after the last operand. It holds
// the closing brackets of every memory form ("}]" for LDR's unsigned offset,
// "]" for LD1's list form), which have no operand to hang off as a Prefix.
AsmSuffix string
// AsmOperands are the <a> operand references inside this encoding's
// asmtemplate, in source order. ARM's hover text names both the operand's
// type and the bit field that encodes it, which is what makes a typed
// assembler surface generatable rather than guessed.
AsmOperands []AsmOperand
// EquivalentOperands are operands named only by an alias's
// <equivalent_to> expansion. They can carry fixed defaults for fields the
// alias syntax hides entirely, such as SYS's optional Rt = 11111 behind
// the bare GCSPOPX mnemonic.
EquivalentOperands []AsmOperand
// EquivalentSuffix is the literal after the final equivalent operand. It
// completes relations split around an anchor, such as #(-<const> - 1).
EquivalentSuffix string
// Explanations is ARM's operand documentation for this instruction page:
// field bindings and enumerated value tables. Not filtered by encoding —
// use ExplanationsFor.
Explanations []AsmExplanation
BitDiffs string
Boxes []RegBox
Pseudocode []string
Features []string
// IsAlias is true when instructionsection@type="alias".
IsAlias bool
// AliasOf is the canonical EncodingID when known (from asmtemplate href fragment).
AliasOf string
// AliasCond is ARM's equality condition for the alias spelling. Besides
// deciding decode preference, it fixes fields hidden by the alias template:
// MOV Vd,Vn aliases ORR Vd,Vn,Vn, so Rm must mirror Rn.
AliasCond string
}
ParsedIForm is the authoritative content extracted from an instructionsection XML file for one encoding (matched by EncodingID / encoding@name).
func ParseIFormFile ¶
func ParseIFormFile(path, encodingID string) (*ParsedIForm, error)
ParseIFormFile loads an iform XML and extracts data for encodingID. encodingID should match <encoding name="…"> (e.g. CLREX_BN_barriers).
type ParsedIFormCache ¶
type ParsedIFormCache struct {
// contains filtered or unexported fields
}
ParsedIFormCache caches ParseIFormFile results keyed by path + encodingID. A non-positive maxSize means unbounded; ARMParser uses that mode because the cache lives for one pipeline run and Pass 3 immediately reuses all Pass 2 forms. Callers processing an open-ended stream can supply a positive bound.
func NewParsedIFormCache ¶
func NewParsedIFormCache(maxSize int) *ParsedIFormCache
func (*ParsedIFormCache) Clear ¶
func (c *ParsedIFormCache) Clear()
func (*ParsedIFormCache) GetOrLoad ¶
func (c *ParsedIFormCache) GetOrLoad(path, encodingID string) (*ParsedIForm, error)
func (*ParsedIFormCache) GetOrLoadCorpus ¶
func (c *ParsedIFormCache) GetOrLoadCorpus(corpus XMLCorpus, name, encodingID string) (*ParsedIForm, error)
func (*ParsedIFormCache) Hits ¶
func (c *ParsedIFormCache) Hits() int64
func (*ParsedIFormCache) Misses ¶
func (c *ParsedIFormCache) Misses() int64
type Placement ¶
type Placement struct {
Param string // Rust parameter expression, e.g. "rn" or "mem.base"
Field string
Start int // low bit
End int // high bit
Width int
// Parts is set when the value spans several fields: one entry per field,
// most significant first. Width is then the total across all parts.
Parts []BitPart
// Scale is the encoding multiplier: a byte offset divides by Scale.
Scale int64
// Signed marks a two's-complement field.
Signed bool
// Lo/Hi bound the accepted value before scaling.
Lo, Hi int64
HasRange bool
// Bias is subtracted before encoding: the SME vector-select register is
// written W12-W15 and held in a 2-bit field as v-12.
Bias int64
// Negate is the constant the field counts down from, 0 when it counts up.
Negate int64
// Default is what ARM encodes when the operand is omitted (RET's Rn = 30).
Default int64
HasDefault bool
// Xor is applied to the raw caller value before placement.
Xor uint32
// RegRanges maps disjoint written register banks into consecutive field
// values.
RegRanges []RegRange
}
Placement binds a method parameter to a bit range in the instruction word.
type PseudocodeParser ¶
type PseudocodeParser struct{}
PseudocodeParser converts pseudocode text into AST nodes. It is stateless and safe for concurrent use by all IForm workers.
func NewPseudocodeParser ¶
func NewPseudocodeParser() *PseudocodeParser
NewPseudocodeParser creates a new pseudocode parser
func (*PseudocodeParser) ParseLines ¶
func (p *PseudocodeParser) ParseLines(lines []string) []ir.PseudocodeLine
ParseLines converts pseudocode lines into PseudocodeLine structures. Individual lines never panic the pipeline: bad ASL falls back to raw-only.
type RawEncoding ¶
type RawEncoding struct {
EncodingID string
Mnemonic string
AsmSyntax string
FixedWord uint32
Pattern string
Fields []RawField
Reason string
}
RawEncoding is an encoding exposed only through the field-level exact API.
type RawField ¶
type RawField struct {
Name string
Start, End int
Width int
// Free masks the bits of this field the encoding leaves settable. A field
// can be partly pinned — UMOV's 64-bit form fixes imm5 to x1000 — and
// writing the whole field would erase the bits that select the element size.
Free uint32
}
RawField is one settable field of an encoding.
type RegBox ¶
type RegBox struct {
Name string
HiBit int
Width int
// Bits holds one character per bit, MSB first (Bits[0] is HiBit):
// '0'/'1' fixed, 'x' variable, '-' inherit from the iclass diagram.
// Per-bit resolution is required because ARM diagrams mix fixed and
// variable bits inside one box (e.g. size with psbits "xx" and <c>1</c><c>x</c>).
Bits string
Fixed *uint64 // set only when every bit in Bits is 0 or 1
// NotEq holds the excluded value from a "!= 0000" style cell, width-aligned
// with the box ('x' = don't-care). ARM uses it to carve one encoding out of
// another's space — SSHR (vector) requires immh != 0000, which is what keeps
// it from colliding with the MOVI modified-immediate group.
NotEq string
PSBits string
}
RegBox is a <regdiagram>/<box> field, or a per-<encoding> override box.
type RegistryStats ¶
type RegistryStats struct {
TotalInstructions int
UniqueMnemonics int
UniqueClasses int
UniqueFeatures int
MostCommonMnemonic string
ClassDistribution map[string]int
FeatureUsage map[string]int
}
RegistryStats holds statistics about the registry
type RustConformanceCase ¶
RustConformanceCase identifies one actual generated typed-method call in the source returned by EmitRustConformanceTest.
func EmitRustConformanceTest ¶
func EmitRustConformanceTest(crateName string, s *AsmSurface) (string, []RustConformanceCase)
EmitRustConformanceTest emits an ignored Rust integration test that calls every typed assembler implementation with the same justified non-zero samples used by the generated unit tests. Each call gets a fresh Assembler so its one output word can be attributed without state leaking between instructions.
The returned program prints "<index>\t<encoding-id>\t<word>" per call. External conformance tooling can render and assemble those words with an independent toolchain, then compare the bytes.
The test is ignored during an ordinary `cargo test` because producing the call ledger is only the first half of conformance. The repository's strict LLVM gate runs this test with --ignored, independently assembles every printable call, and requires byte-identical output.
func EmitRustExactConformanceTest ¶
func EmitRustExactConformanceTest(crateName string, s *AsmSurface) (string, []RustConformanceCase)
EmitRustExactConformanceTest emits one ignored integration-test call for every exact encoder in the generated crate. Unlike the typed ledger, this is exhaustive over the resolved instruction corpus.
func EmitRustExactConformanceTestFor ¶
func EmitRustExactConformanceTestFor( crateName string, s *AsmSurface, disasm *DisasmSurface, ) (string, []RustConformanceCase)
type SymbolValue ¶
type SymbolValue struct {
// Bits holds one bit pattern per entry in the owning explanation's Fields,
// in the same order. 'x' appears as a don't-care.
Bits []string
// Symbol is the assembler spelling this combination selects, e.g. "8B".
// "RESERVED" marks an unallocated combination.
Symbol string
}
SymbolValue is one row of an operand's value table.
func (SymbolValue) Reserved ¶
func (v SymbolValue) Reserved() bool
Reserved reports whether this row is an unallocated combination.
type TarXMLCorpus ¶
type TarXMLCorpus struct {
// contains filtered or unexported fields
}
TarXMLCorpus is a prepared, immutable view of a tar stream. The loader consumes gzip/tar sequentially and retains compact ParsedIForm models rather than the expanded XML members. Only encodingindex.xml remains as raw XML for Pass 1; it is released immediately after that pass.
func LoadTarXMLCorpus ¶
func LoadTarXMLCorpus(r io.Reader, source string) (*TarXMLCorpus, error)
func LoadTarXMLCorpusWithOptions ¶
func LoadTarXMLCorpusWithOptions(r io.Reader, source string, options TarXMLCorpusOptions) (*TarXMLCorpus, error)
func OpenTarXMLCorpus ¶
func OpenTarXMLCorpus(ctx context.Context, location string) (*TarXMLCorpus, error)
func OpenTarXMLCorpusWithOptions ¶
func OpenTarXMLCorpusWithOptions(ctx context.Context, location string, options TarXMLCorpusOptions) (*TarXMLCorpus, error)
func (*TarXMLCorpus) Close ¶
func (c *TarXMLCorpus) Close() error
func (*TarXMLCorpus) Description ¶
func (c *TarXMLCorpus) Description() string
func (*TarXMLCorpus) OpenXML ¶
func (c *TarXMLCorpus) OpenXML(name string) (io.ReadCloser, error)
func (*TarXMLCorpus) Stats ¶
func (c *TarXMLCorpus) Stats() TarXMLCorpusStats
type TarXMLCorpusOptions ¶
TarXMLCorpusOptions bounds the concurrent preparation stage. One member larger than MaxInflightBytes is admitted alone, so the actual hard bound is max(MaxInflightBytes, the largest allowed XML member).
type TarXMLCorpusStats ¶
type ValidationError ¶
ValidationError records one consistency problem on an instruction. Cherry-picked from improved-parser-design utilities.InstructionValidator.
func (ValidationError) String ¶
func (e ValidationError) String() string
type ValueChoice ¶
ValueChoice is one exact spelling/value pair accepted by a built-in operand type such as Extend. These operands use shared Rust enums, but each encoding accepts only the rows listed in its own ARM value table.
type XMLCorpus ¶
type XMLCorpus interface {
OpenXML(name string) (io.ReadCloser, error)
Description() string
}
XMLCorpus provides the logical XML documents used by the ARM pipeline. Directory corpora expose every document. Streaming tar corpora retain only encodingindex.xml and serve IForms from their prepared compact models.
Source Files
¶
- alias_index.go
- arch.go
- arm_parser.go
- bitdiffs.go
- codegen.go
- codegen_go.go
- codegen_license.go
- codegen_model.go
- codegen_rust.go
- codegen_rust_asm.go
- codegen_rust_asm_test_emit.go
- codegen_rust_disasm.go
- conformance_sample.go
- disasm_model.go
- disasm_render.go
- encoding_handlers.go
- encodingindex.go
- explanations.go
- feature_tags.go
- fs_other.go
- go_conformance.go
- iform_cache.go
- iform_parse.go
- operand_class.go
- operand_infer.go
- pseudocode_parser.go
- registry.go
- rust_api.go
- rust_asm_conformance.go
- rust_asm_model.go
- validate.go
- xml_corpus.go