Expand description
§fARM64 — a pure-Rust AArch64 (A64) disassembler and semantic encoder
fARM64 decodes 64-bit ARM (AArch64 / A64) machine code into a rich,
Copy value-type Instruction, renders it with a pluggable Formatter,
and re-encodes instruction semantics with encode() — including after
editing its operands. The Arm architectural
decode tree is hand-written from the Arm Architecture Reference Manual (the
“Arm ARM”) and cross-checked during development against independent tools
and corpora. Apple AMX and GXF are implementation-defined exceptions based
on public reverse-engineering references and are separately runtime-gated.
§Portability is a hard, cross-cutting guarantee
This crate is #![no_std] unconditionally. The core decode path and the
default formatter perform zero heap allocation and have no dependency
on alloc or std at all:
- The decoder (
Decoder::decode_into) writes into a caller-owned,CopyInstruction; there is noVec, noBox, no internal pointers. - The default formatter (
format::FmtFormatter) writes into a caller-suppliedcore::fmt::Writesink or a fixed&mut [u8]buffer viaformat::BufSink(with overflow tracking, never overrun). - All names (registers, mnemonics, system registers) are
&'static strsourced fromconst/statictables. - No thread-locals, no environment/IO/time access, no panics-as-control-flow, deterministic, and no floating-point arithmetic in the decoder.
Builds cleanly for hosted targets, wasm32-unknown-unknown, and
aarch64-unknown-none (freestanding / no-CRT, no allocator).
§Feature matrix
| Feature | Tier | Effect |
|---|---|---|
| (none / default) | A | no_std, no alloc, freestanding. Decoder + format::FmtFormatter + all enums. Always builds. |
alloc | B | Adds String/Vec conveniences (format_to_string, a cached info::InstructionInfoFactory, and a token-collecting String sink). |
std | C | Implies alloc; adds std::error::Error for DecodeError, EncodeError, and EnumValueError, plus std-only test/bench helpers. |
fmt-gnu | A | Adds a UAL-equivalent GNU compatibility adapter. Pure no_std. |
sve | A | Compiles the SVE/SVE2 decoder and encoder modules. |
sme | A | Compiles the SME/SME2 decoder and encoder modules. |
crypto | A | Compiles the Advanced SIMD crypto decoder; public enums and encoder support remain present. |
full | A | Enables sve, sme, and crypto. |
Cargo features decide which optional implementation modules are compiled;
the runtime FeatureSet decides what is accepted at decode time. Not
every runtime extension has a corresponding Cargo feature.
§Supported targets
| Target | Notes |
|---|---|
x86_64-*, aarch64-* (hosted) | development / std testing |
wasm32-unknown-unknown | default features (no_std, no alloc) |
aarch64-unknown-none | bare-metal, no-CRT; checked with --no-default-features |
any target providing core | the default tier is core-only |
§Quick start (zero-alloc, no_std-friendly)
use fARM64::{Decoder, DecoderOptions, format::{Formatter, FmtFormatter, BufSink}};
// `ADD W0, W1, #1` little-endian; decode at a known address.
let code = [0x20, 0x04, 0x00, 0x11];
let mut dec = Decoder::new(&code, 0x1000, DecoderOptions::default());
let insn = dec.decode();
// Format into a fixed stack buffer — no heap involved.
let mut buf = [0u8; 64];
let mut sink = BufSink::new(&mut buf);
FmtFormatter::new().format(&insn, &mut sink);
let _text: &str = sink.as_str();§Editing and re-encoding
encode() rebuilds the word from an Instruction’s semantics and
never reads Instruction::word, so changing the operands and encoding
again yields the word for the changed instruction:
use fARM64::{Decoder, DecoderOptions, Register};
// `ldr x0, [x1, #8]` -> `ldr x0, [x3, #16]`
let bytes = 0xF940_0420u32.to_le_bytes();
let mut insn = Decoder::new(&bytes, 0, DecoderOptions::NONE).decode();
assert!(insn.set_memory_base(Register::X3));
assert!(insn.set_memory_displacement64(16));
assert_eq!(insn.encode(), Ok(0xF940_0860));Every setter is total: it returns false rather than panicking when the edit
does not apply, and a value with no valid field encoding surfaces as an
EncodeError from encode(). See
the editing rules.
§Implicit register reads and writes
A64 hides real dataflow behind the mnemonic — BL writes X30, PACIASP
read-modifies X30 using SP, LD64B <Xt> writes Xt..Xt+7, LDFF1*
read-modifies the SVE FFR, ADR reads PC. implicit_registers()
reports all of it, using the Register::Nzcv / Register::Ffr /
Register::Za / Register::Pc pseudo-registers for state that has no
numbered register. instruction_info() merges the list into its
used_registers access set.
§Licensing & provenance
Licensed under the MIT License. Arm architectural instruction handling is based on the publicly documented Arm ARM. The implementation also contains separately gated Apple implementation-defined AMX/GXF support based on public reverse-engineering references: https://github.com/corsix/amx, https://asahilinux.org/docs/hw/cpu/apple-instructions/, and https://blog.svenpeter.dev/posts/m1_sprr_gxf/.
Re-exports§
pub use crate::decoder::Decoder;pub use crate::decoder::DecoderIntoIter;pub use crate::decoder::DecoderIter;pub use crate::decoder::DecoderOptions;pub use crate::encode::encode;pub use crate::encode::EncodeError;pub use crate::enums::Condition;pub use crate::enums::ExtendType;pub use crate::enums::FlagEffect;pub use crate::enums::FlowControl;pub use crate::enums::ShiftType;pub use crate::enums::VectorArrangement;pub use crate::error::DecodeError;pub use crate::features::Feature;pub use crate::features::FeatureSet;pub use crate::format::Formatter;pub use crate::format::FormatterOptions;pub use crate::format::FormatterOutput;pub use crate::format::SymbolResolver;pub use crate::format::SymbolResult;pub use crate::format::TokenKind;pub use crate::implicit::implicit_registers;pub use crate::implicit::ImplicitRegisters;pub use crate::implicit::MAX_IMPLICIT_REGS;pub use crate::info::instruction_info;pub use crate::info::InstructionInfo;pub use crate::info::OpAccess;pub use crate::info::UsedMemory;pub use crate::info::UsedRegister;pub use crate::instruction::Instruction;pub use crate::mnemonic::Code;pub use crate::mnemonic::EnumValueError;pub use crate::mnemonic::Mnemonic;pub use crate::operand::MemIndexMode;pub use crate::operand::OpKind;pub use crate::operand::Operand;pub use crate::operand::PredQual;pub use crate::operand::SliceIndicator;pub use crate::operand::SveMemMode;pub use crate::register::gp_register;pub use crate::register::sve_register;pub use crate::register::RegClass;pub use crate::register::RegWidth;pub use crate::register::Register;pub use crate::sysreg::SystemReg;pub use crate::format::format_to_string;alloc
Modules§
- decode
- The hand-written recursive A64 decode tree (derived from the ARM ARM).
- decoder
- The borrowing, zero-alloc
Decoder— the primary entry point. - encode
- The hand-written A64 encoder — the inverse of
decode. - enums
- Small public enums shared across the API: condition codes, shift/extend modifiers, vector arrangements, and flow/flag classifications.
- error
- The core decode-error enum.
- features
- Architecture-extension model.
- format
- Formatting: turn an
Instructioninto text, zero-alloc by default. - implicit
- Implicit register reads/writes — the architectural state an instruction
touches without naming it in an operand (the link register, the pointer-
authentication
X30/SP/X16/X17, the FEAT_LS64Xt+1..Xt+7group, the SVEFFR,PCfor PC-relative address generation, and theNZCVflags). Implicit register reads and writes — the architectural state an A64 instruction touches without naming it in an operand. - info
- Instruction flow / register-and-memory access analysis (iced
InstructionInfoanalog). - instruction
- The
Copyvalue-typeInstruction— the public projection of a decoded A64 instruction. - mnemonic
- The two large public enums:
Code(one variant per ARM encoding row) andMnemonic(width/encoding-independent instruction name). - operand
- The rich, safe,
CopyOperandenum and itsOpKinddiscriminant view. - register
- Typed registers with stack/zero resolution baked in.
- sysop
- Fixed system-instruction operation and option name tokens.
- sysreg
- System-register identity and naming.
- tables
- Mechanical name / enum lookup tables (the
&'static strregister, condition, and system-register name tables). These are maintained as committed Rust source and contain no decode logic. The workspace’sxtaskis currently only a scaffold for a possible future generator. Mechanical name / enum lookup tables.
Constants§
- INSN_
LEN - Fixed A64 instruction length, in bytes. A64 is a fixed-width ISA: every
instruction is exactly 4 bytes and 4-byte aligned, and
PCalways advances by 4. Exposed for callers that stride a buffer. - MAX_
OPERANDS - The maximum number of explicit operands any A64 encoding produces.