arm

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 6, 2026 License: MIT Imports: 30 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrCorpusEntryUnavailable = errors.New("corpus entry unavailable")

Functions

func AlternativeOperands

func AlternativeOperands(asmTemplate string) map[int]bool

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

func AsmMnemonic(asmTemplate string) string

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

func ExpandWidthCases(params []Param) [][]Param

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

func LiteralBits(s string) (string, bool)

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

func MethodName(mnemonic string) string

MethodName maps an assembler mnemonic to a snake_case Rust method name.

func NewBitfieldHandler

func NewBitfieldHandler() parse.Handler

NewBitfieldHandler creates a handler for bitfield cells

func NewFeatureHandler

func NewFeatureHandler() parse.Handler

NewFeatureHandler creates a handler for feature tags

func NewInstructionRowHandler

func NewInstructionRowHandler() parse.Handler

NewInstructionRowHandler creates a handler for instruction rows

func NewInstructionTableHandler

func NewInstructionTableHandler() parse.Handler

NewInstructionTableHandler makes an instruction table's class available to its row handlers through the parser's lexical scope stack.

func NewMnemonicHandler

func NewMnemonicHandler() parse.Handler

NewMnemonicHandler creates a handler for mnemonic cells

func OrdinalMember

func OrdinalMember(prose string) bool

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) Close

func (ap *ARMParser) Close(timeout time.Duration) error

Close cleans up resources

func (*ARMParser) DisasmSurface

func (ap *ARMParser) DisasmSurface() *DisasmSurface

DisasmSurface projects resolved IR into the print model. Valid after Parse.

func (*ARMParser) GetMetrics

func (ap *ARMParser) GetMetrics() map[string]interface{}

GetMetrics returns parsing metrics

func (*ARMParser) GetRegistry

func (ap *ARMParser) GetRegistry() *InstructionRegistry

GetRegistry returns the instruction registry

func (*ARMParser) Parse

func (ap *ARMParser) Parse(ctx context.Context) error

Parse executes the 3-pass parsing pipeline

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 ParseArch

func ParseArch(s string) (Arch, error)

ParseArch validates an -arch value.

func SupportedArches

func SupportedArches() []Arch

SupportedArches lists the architectures this build can generate.

func (Arch) ArtifactName

func (a Arch) ArtifactName() string

ArtifactName is the Rust crate name and Go module name for this target.

func (Arch) SpecIndexFile

func (a Arch) SpecIndexFile() string

SpecIndexFile is the index file the architecture's spec tree is rooted at.

type ArityGroup

type ArityGroup struct {
	Method string
	Arity  int
	Forms  []AsmForm
}

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
	// Shared is the subset of Mask an earlier operand already committed. Those
	// 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 ArrRow

type ArrRow struct {
	Symbol string
	Bits   []string
}

ArrRow is one legal arrangement and the bits it sets, per field in order.

type ArrSpec

type ArrSpec struct {
	Fields []string
	Rows   []ArrRow
}

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 Bitfield

type Bitfield struct {
	Position int
	Width    int
	Value    string
	Name     string
}

Bitfield represents a parsed bitfield

type BitfieldHandler

type BitfieldHandler struct {
	// contains filtered or unexported fields
}

BitfieldHandler handles <td class="bitfield"> elements

func (*BitfieldHandler) End

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 ClassEncoderRef struct {
	Class     string
	FieldName string
	TypeName  string
}

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 DecoderData struct {
	Package    string
	Tree       *ir.DecoderTree
	Classes    []string
	LeafCount  int
	NodeCount  int
	InstrCount int
}

type DerivedRel

type DerivedRel struct {
	Field string
	Mul   int64
	Add   int64
	Mod   int64
	Const int64
}

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

type DisasmForbidden struct {
	Mask, Value uint32
	Mutable     uint32
}

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 DisasmFormulaExpr struct {
	Parts     []BitPart
	RawMul    int64
	Add       int64
	Negate    int64
	SizeParts int
	ESizeBase int64
	ESizeMul  int64
}

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 DisasmMoveWideZeroGuard struct {
	Imm16 BitPart
	HW    BitPart
}

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.

func (*DisasmOperand) Render

func (o *DisasmOperand) Render(word uint32) (string, bool)

Render prints one operand slot.

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 DisasmRow

type DisasmRow struct {
	Bits   []string
	Symbol string
}

DisasmRow is one row of an operand's value table.

type DisasmSkip

type DisasmSkip struct {
	EncodingID string
	Symbol     string
	Reason     string
}

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 FixedBitData struct {
	Start int
	End   int
	Value uint64
}

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

type GoConformanceField struct {
	Name  string
	Value uint64
}

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 MasterDispatchEntry struct {
	EncodingID string
	Class      string
	FieldName  string
	FuncName   string
}

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 OperandEncoderData struct {
	Operand   ir.OperandIR
	ParamName string
	ParamType string
}

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 RegRange

type RegRange struct {
	Lo, Hi int64
	Bias   int64
}

RegRange maps raw = written register - Bias for one accepted run.

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

type RustConformanceCase struct {
	EncodingID string
	Method     string
}

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

type TarXMLCorpusOptions struct {
	Workers          int
	MaxInflightBytes int64
}

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 TarXMLCorpusStats struct {
	XMLMembers          int
	IFormPages          int
	PreparedIForms      int
	PreparedAliases     int
	ExpandedXMLBytes    int64
	PeakInflightBytes   int64
	RetainedRawXMLBytes int64
}

type ValidationError

type ValidationError struct {
	InstructionID string
	Field         string
	Message       string
}

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

type ValueChoice struct {
	Symbol string
	Value  uint32
}

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 WidthCase

type WidthCase struct {
	Symbol   string
	RustType string
	Bits     []string
}

WidthCase is one register width a width-specifier position accepts.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL