A routine body may now be written as inline assembly:
function GetSelf: Pointer; assembler; nostackframe;
asm
movq %rdi, %rax
ret
end;
The block is opaque GNU/AT&T assembly: the lexer captures the whole asm … end
as one tkAsmBlock token (verbatim text, never tokenised as Pascal), the parser
wraps it in a TAsmStmt, the semantic pass treats it as a black box, and the
native backend emits it verbatim into the assembly stream where the existing
internal/external assembler parses it. `nostackframe` suppresses the compiler
prologue/epilogue so the asm body owns the whole frame. asm routines mix
freely with ordinary Pascal routines in a standard .pas unit (no .inc needed).
This is the FPC model (rtl/linux/x86_64/si_c.inc) and the path to retiring the
hand-written runtime/src/main/asm/*.s files (assembled by `cc -c` today) — once
each body moves into an asm routine the RTL builds with no external assembler.
Design follows ports-and-adapters: x86-64 knowledge stays at the backend/
assembler edge, the portable core never interprets the block. The QBE backend
rejects asm bodies (it emits no assembly text); native is the inline-asm target
and the default. TAsmStmt round-trips through the .bif unit cache.
Pipeline: lexer (tkAsmBlock + ReadAsmBody raw capture), uAST (TAsmStmt,
TMethodDecl.NoStackFrame), parser (nostackframe directive + asm-body path),
semantic (opaque no-op), native codegen (verbatim emit + nostackframe null-frame
guard), QBE rejection, uUnitInterfaceIO encode/decode, bif-coverage entry.
`asm` becomes a reserved word (one local var named Asm renamed in a test).
Fixes a native sret-Result field-read codegen bug the feature exposed: reading a
field of an sret function's Result at offset 0 (e.g. `Result.Kind` in a record-
returning function) read the Result frame slot DIRECTLY instead of dereferencing
the caller-buffer pointer it holds, so `Result.Field = const` was always false.
The offset-0 fast path in the integer field-read leaf now routes through
EmitLocalRecordBase like the offset>0 path, so the sret indirection happens in
both. QBE was already correct; this was a native-only divergence.
Tests: lexer raw-capture (3), native verbatim-body/no-prologue IR test (1),
internal-assembler e2e returns-value + adds-two-args (2). All four fixpoints
and both QBE- and native-built test runners pass (3764 tests).
Design note: docs/inline-asm-design.adoc; grammar + rationale updated.