← board

Unify inline asm onto the existing per-target text-assembler engine

Corrected understanding (read this first)

This ticket was originally going to propose a brand-new structured instruction-list IR. That was wrong — it already exists, just not wired to user-facing inline asm:

compiler/asmtext.inc + asmtext_386.inc / asmtext_a64.inc / asmtext_arm32.inc / asmtext_rv32.inc / asmtext_xtensa.inc implement EmitAsmX64 / EmitAsm386 / EmitAsmA64 / EmitAsmArm32 / EmitAsmRv32 / EmitAsmXtensaone per target, all six already exist. Each takes an interleaved array of const (instruction-text lines + %-hole int values), and already has:

It's used today as an internal codegen-authoring convenience — ir_codegen*.inc backends call these with literal Pascal string constants instead of hand writing raw bytes. Call-site counts show very uneven adoption per backend (2026-06-30 audit): ir_codegen.inc(x64) 3, ir_codegen386.inc 4, ir_codegen_aarch64.inc 10, ir_codegen_arm32.inc 16, ir_codegen_riscv32.inc 11, ir_codegen_xtensa.inc 40 — xtensa/arm32/aarch64/ riscv32 lean on it heavily, x64/i386 (older backends) mostly still call typed x64enc.inc/raw EmitB directly. The closed ticket that built the xtensa emitter (devdocs/progress/done/feature-xtensa-asm-emitter.md) says outright: "it doubles as the backend for eventual Xtensa inline asm … end" — this work was always the intended direction, just never finished.

compiler/asmenc.inc (the actual asm...end / assembler Pascal-block parser) is a separate, older, x86-64-only implementation that does not use any of the above — it encodes straight into a flat byte buffer at parse time with no symbolic/relocation layer, which is the real reason labels, branches, and globals don't work in inline asm today.

Goal

Wire compiler/asmenc.inc's parser onto the existing EmitAsmX64 / EmitAsm386 / EmitAsmA64 / EmitAsmArm32 / EmitAsmRv32 / EmitAsmXtensa engines instead of its own flat-byte path. Concretely:

Per-target rollout

Because all six EmitAsmXxx engines already exist (with varying maturity — see call-site counts above), multi-arch inline asm becomes wiring the parser-side identifier resolution per target, not building six new encoders from scratch. Land x86-64 first (closes [[feature-inline-asm-depth]] TODO #1-2), then i386/aarch64/arm32/riscv32/ xtensa — see corrected scope note on [[feature-inline-asm-multi-arch]].

Scope (this ticket)

Acceptance

Self-hosting constraint

Same as asmenc.inc today (see devdocs/developer/inline-asm.md bottom section): no string + on the hot path, build strings with AppendChar — the bootstrap compiler must compile this file. (asmtext.inc already observes this discipline — match it.)

Log