feat(asm): assemble the extended instruction layer on arm64

Assisted-by: GLM 5.3 Flash
This commit is contained in:
petrbalvin committed 2026-10-07 02:23:37 +02:00
1 parent c2adde948f
commit 9c951c232e
3 files changed
+420

No files matched your search

+25
View File
@@ -9,6 +9,7 @@ import (
"strconv"
"strings"
"sourcedock.dev/petrbalvin/gasm-sdk/arch"
"sourcedock.dev/petrbalvin/gasm-sdk/ast"
)
@@ -269,6 +270,13 @@ func arm64InstrSize(instr *ast.Instr, fi arm64FrameInfo, pos int) int {
case "NO_LOCAL_POINTERS", "GO_ARGS", "GO_RESULTS_INITIALIZED", "END", "FUNCDATA", "PCDATA":
return 0
}
// The extended-instruction layer is one instruction word in every form
// the registry takes: pass 1 must size a pinned statement at the 4 bytes
// the encoder will lay down, ahead of the scalar immediate expansions
// below, whose sizes would misread a Z destination (asm/arm64_ext.go).
if _, pinned, _ := arm64ExtStatement(mnem, ops); pinned {
return 4
}
switch mnem {
case "MOV", "MOVD", "MOVW", "MOVWU", "MOVH", "MOVHU", "MOVB", "MOVBU",
"FMOVS", "FMOVD":
@@ -307,6 +315,23 @@ func encodeARM64Instr(instr *ast.Instr, pc int, offsets map[string]int, fi arm64
mnem := strings.ToUpper(instr.Mnemonic.Text)
ops := instr.Operands
// The extended-instruction layer: a statement whose mnemonic is
// registered in the extension registry and whose operands carry a
// scalable vector or predicate register encodes through the registry,
// before any scalar route can misread those operands. Scalar, NEON and
// FP operand lists never pin, so everything below runs exactly as it
// did (asm/arm64_ext.go).
if extops, pinned, convErr := arm64ExtStatement(mnem, ops); pinned {
if convErr != nil {
return nil, convErr
}
code, encErr := EncodeExtension(arch.ARM64, mnem, extops...)
if encErr != nil {
return nil, encErr
}
return code, nil
}
// Pseudo-instructions and special cases first.
switch mnem {
case "RET":